ObjectInfo class is a diagnostic class intended to track statistical data such as life time and number of objects. A specific class inherits from ObjectInfo as shown. A member of that specific class is then declared in the body of a profiled class.
Although the solution works it is hard to maintain as it requires the profiling class to be keep in sync with the profiled class as the class name is used to identify the later. It would also be hard to extend the profiling class to gather different information such as the size of object.
Propose a better solution where the dependencies between the profiled and profiling classes are minimal.
Is it possible to implement a check that would determine if the object of the profiled class was created on stack or heap?
-- ObjectInfo.h --
#pragma once
class ObjectInfo
{
public:
ObjectInfo(const char* objectName);
virtual ~ObjectInfo(void);
private:
static int m_counter;
int m_objectNumber;
const char* m_className;
};
-- ObjectInfo.cpp --
#include "StdAfx.h"
#include "ObjectInfo.h"
#include <iostream>
#include "TimePrinter.h"
using namespace std;
int ObjectInfo::m_counter = 0;
ObjectInfo::ObjectInfo(const char* name) :
m_className(name)
{
m_objectNumber = ++m_counter;
cout << "Object: " << m_className << "# " << m_objectNumber << " created # " <<
TimePrinter()<< endl;
}
ObjectInfo::~ObjectInfo(void)
{
cout << "Object: " << m_className << "# " << m_objectNumber << " destroyed # " <<
TimePrinter() << endl;
}
-- The use pattern --
struct _AInfo : public ObjectInfo {
_AInfo() : ObjectInfo("_A") {}
};
struct _A {
_AInfo m_info;
};
I originally thought this question is asking about using C++ reflection technique to gather the runtime information. However, I don't know if there is a way to measure the lifetime of objects using C++ reflection. Furhter, can you consider C++ reflection is a technique that reduces the dependencies between the profiled and profiling classes ?
This can track stack vs. heap object creations
#include <iostream>
template <class CRTP>
struct AllocationTracker
{
AllocationTracker()
{
++totalCreated;
}
void* operator new(size_t sz)
{
++heapCreated;
return ::operator new(sz);
}
static int totalCreated;
static int heapCreated;
};
template <class CRTP>
int AllocationTracker<CRTP>::totalCreated;
template <class CRTP>
int AllocationTracker<CRTP>::heapCreated;
class Derived : public AllocationTracker<Derived>
{
};
int main()
{
using namespace std;
cout << Derived::heapCreated << "/" << Derived::totalCreated << endl; // 0/0
Derived dStack;
cout << Derived::heapCreated << "/" << Derived::totalCreated << endl; // 0/1
Derived* dHeap = new Derived;
cout << Derived::heapCreated << "/" << Derived::totalCreated << endl; // 1/2
}
This uses the CRTP that Bartek brought up in the comments on your question. This lets us track each derived type separately. It also wraps the standard new for the base class, which is inherited by derived classes, which allows us to track heap allocations. So we know how many instances are created, and how many on the heap, and we can infer that the rest were on the stack (unless you're using object pools or some other more exotic allocation strategies in your program).
Related
Is the use of new/delete appropriate here? Or any way to avoid them?
The point: class myOptions need an instance of Submarine. The Parameter are known at the time the myOptions-Construcor is called.
#include <iostream>
#include <string>
class Submarine
{
public:
Submarine(std::string o)
{
std::cout << "create class Submarine: " << o << "\n";
}
~Submarine(){};
};
class myOptions
{
public:
myOptions(std::string o):option(o)
{
std::cout << "create class myOption: " << option << "\n";
submarine = new Submarine(option);
}
~myOptions()
{
delete submarine;
}
private:
std::string option{};
Submarine *submarine;
};
int main(void){
myOptions{"help"};
}
You don't need to use dynamic memory here:
class myOptions
{
public:
myOptions(std::string o):option(o), submarine(o)
{
std::cout << "create class myOption: " << option << "\n";
}
private:
std::string option{};
Submarine submarine;
};
If you really need to use dynamic memory allocation (and you are not allowed to use smart pointers), you must apply the rule of five to your class. Currently it will blow up your program anytime you decide to pass it by value.
Changing values of classes/structs inside classes are a mystery to me. I tried to do some research today and came up with the following solution. I wonder if this is a proper way for a function to change stuff inside the class. Is there a need to for this to be somehow done with pointers? Is there a more proper way to accomplish this?
#include <iostream>
int main()
{
class Someclass {
private:
int Integer;
public:
Someclass(int i):
Integer(i){} //CTOR
struct Somestruct {
int a, b;
};
Somestruct Mystruct;
void func(){
Mystruct.a = Integer/2;
Mystruct.b = Integer*2;
};
};
Someclass A(10);
A.func();
std::cout << A.Mystruct.a << " " << A.Mystruct.b << std::endl;
}
The reason I am writing this code, is because I want to parse a file, starting from the line "Integer" into a customly defined struct "Mystruct" which this class should somehow deliver me. Is this an acceptable way to write such a code?
I understand that your question is about encapsulation, being understood that the inner struct is a data holder and the outer class has to manage it somehow.
Weaknesses of your design
In your design, Mystruct is public. So anything outside Someclass could access the data, but also change it. This is error prone, as there is no guarantee that the outside code doesn't break some invariant of the structure.
Ways for improvement
The cleanest thing would certainly to make some getters and setters to access the data. But with 30 members, it's a lot of code.
If your construction process initialises the struture's data, a second approach could be to limit outside access to read-only. You'd do that by making Mystruct private and offering a function returning a const reference:
class Someclass {
Somestruct Mystruct;
public:
...
const Somestruct& get() { return Mystruct; }
};
std::cout << A.get().a << " " << A.get().b << std::endl;
Online demo
Nevertheless before going into that direction, I'd check if access to the structure's raw data couldn't be encapsulated, for example by providing functions that manage the data without need to know the internals:
class Somestruct {
...
public:
ostream& show_simplified_specs(ostream& os) {
os << a << " " << b;
}
}
A third approach could be to use the builder design pattern to encapsulate the construction process of a Someclass based on Somestruct and other parts.
Pointers ?
Pointers should be avoided if possible. For example, suppose you have a vector of Someclass to keep all these classes in memory. At a moment in time, you get a pointer to an element's Mystruct. Suppose you'd then add a new item to the vector: all the previous pointers might get invalidated.
This same risk potentially exist with references. But I think that while it's a common idiom to cache a pointer returned by a function,in practice it's less common and appealing to copy a reference returned by a function.
Is this what you're looking for? I'm not much confident I understood you right.
template <int I>
struct Someclass;
template <>
struct Someclass<1>
{
int Integer = 1;
int a, b;
void func()
{
a = Integer/2;
b = Integer*2;
}
};
template <>
struct Someclass<2>
{
int Integer = 2;
int a, b, c;
void func()
{
a = Integer/2;
b = Integer*2;
c = Integer*Integer;
}
};
int main()
{
Someclass<1> A;
A.func();
std::cout << A.a << " " << A.b << std::endl;
Someclass<2> B;
B.func();
std::cout << B.a << " " << B.b << " " << B.c << std::endl;
return 0;
}
I am attempting to use static polymorphism to create a decorator pattern.
As to why I do not use dynamic polymorphism, please see this QA. Basically, I could not dynamic_cast to each decorator so as to access some specific functionality present only in the decorators (and not in the base class A).
With static polymorphism this problem has been overcome, but now I cannot register all the et() methods from the decorators back to the base class A (as callbacks or otherwise), thus when A::et() gets called, only A::et() and Z::et() get executed. I want all of A,X,Y,Z ::et() to be executed (the order for X,Y,Z does not matter).
How can I do that using the following structure?
I can see in wikipedia that CRTP should allow you to access member of a derived class using static_cast, but how do you approach the problem when there are multiple derived template classes?
If this is not possible with static polymorphism but it is possible with dynamic polymorphism could you reply to the other question?
struct I {
virtual void et() = 0;
};
class A : public I {
public:
A() {
cout << "A::ctor " ;
decList.clear();
}
void regDecorator(I * decorator)
{
if (decorator) {
cout << "reg= " << decorator << " ";
decList.push_back(decorator);
}
else
cout << "dec is null!" <<endl;
}
virtual void et()
{
cout << "A::et ";
cout << "declist size= " << decList.size() << endl;
list<I*>::iterator it;
for( it=decList.begin(); it != decList.end(); it++ )
static_cast<I *>(*it)->et();
}
std::list<I*> decList; //FIXME
};
template<typename Base>
class X: public Base {
public:
X(){
cout << "X::ctor ";
Base::regDecorator(this);
}
virtual void et(){
cout << "X::et" <<endl;
}
};
template<typename Base>
class Y: public Base {//public D {
public:
Y(){
cout << "Y::ctor ";
Base::regDecorator(this);
}
void et(){
cout << "Y::et" <<endl;
}
};
template<typename Base>
class Z: public Base {//public D {
public:
Z() {
cout << "Z::ctor ";
Base::regDecorator(this);
}
void et(){
cout << "Z::et" <<endl;
}
};
int main(void) {
Z<Y<X<A> > > mlka;
cout << endl;
mlka.et();
return 0;
}
This structure is to be used as a reference for data acquisition from a set of sensors. class A is the base class and contains common functionality of all the sensors. This includes:
- data container (f.e. `boost::circular_buffer`) to hold an amount of timestamped sample data acquired from the sensor.
- a Timer used to measure some timed quantities related to the sensors.
- other common data and calculation methods (fe. `calculateMean()`, `calculateStdDeviation()`)
In fact the A::timer will call A::et() on completion in order to perform some statistical calculations on the sampled data.
Similarly, X,Y,Z are types of sensor objects each with responsibility to extract different type of information from the sampled data. and X,Y,Z::et() perform a different type of statistical calculation on the data. The aim is perform this calculation as soon as the A::Timer waiting time elapses. This is why I want to have access to all of X,Y,Z::et() from A::et(). Is it possible without affecting the static polymorphism shown in the example?
Thank you
You started using mixins, so use them to the end.
It follows a minimal, working example:
#include<iostream>
struct I {
virtual void et() = 0;
};
template<typename... T>
struct S: I, private T... {
S(): T{}... {}
void et() override {
int arr[] = { (T::et(), 0)..., 0 };
(void)arr;
std::cout << "S" << std::endl;
}
};
struct A {
void et() {
std::cout << "A" << std::endl;
}
};
struct B {
void et() {
std::cout << "B" << std::endl;
}
};
int main() {
I *ptr = new S<A,B>{};
ptr->et();
delete ptr;
}
As in the original code, there is an interface I that offers the virtual methods to be called.
S implements that interface and erases a bunch of types passed as a parameter pack.
Whenever you invoke et on a specialization of S, it invokes the same method on each type used to specialize it.
I guess the example is quite clear and can serve as a good base for the final code.
If I've understood correctly the real problem, this could be a suitable design for your classes.
EDIT
I'm trying to reply to some comments to this answer that ask for more details.
A specialization of S is all the (sub)objects with which it is built.
In the example above, S<A, B> is both an A and a B.
This means that S can extend one or more classes to provide common data and can be used as in the following example to push around those data and the other subobjects:
#include<iostream>
struct I {
virtual void et() = 0;
};
struct Data {
int foo;
double bar;
};
template<typename... T>
struct S: I, Data, private T... {
S(): Data{}, T{}... {}
void et() override {
int arr[] = { (T::et(*this), 0)..., 0 };
(void)arr;
std::cout << "S" << std::endl;
}
};
struct A {
void et(Data &) {
std::cout << "A" << std::endl;
}
};
struct B {
void et(A &) {
std::cout << "B" << std::endl;
}
};
int main() {
I *ptr = new S<A,B>{};
ptr->et();
delete ptr;
}
I have the following code:
// Example program
#include <iostream>
#include <string>
#include <typeinfo>
using namespace std;
class Name
{
int a;
int b;
};
class Name1
{
int a;
int b;
};
int main()
{
Name1* name1;
Name* name;
// trying to implement the following code:
// check if name1 is of type of pointer Name1 then do someting
// check if name is of type of pointer Name then do someting
}
how to check the type of pointer name1?
Name1 and Name are not inherited, the dynamic_cast can not be used, then how to check the type of a pointer?
Compile time differenciation:
You can use a template and its specialisation:
template <class T>
bool isName(T *t) { return false; } // normal case returns false
template <>
bool isName(Name *t) { return true; } // but for Name returns true
Then you can differentiate your code, for example:
Name *n; Name1 *n1;
cout << "(1): " << isName(n) << endl;
cout << "(2): " << isName(n1) << endl;
You can of course use isName() in conditions to process depending on the class of the object.
From a design perspective, if you have class specific code, it may however be more interesting to wrap it in some templates, and use the specialisation demonstrated above, not for returning a boolean, but doing what is to be done, for example:
template <class T>
void doMyStuff(T *t) { } // in general do nothing
template <>
void doMyStuff(Name *t) { cout << "do something with Name*"<<endl; }
template <>
void doMyStuff(Name1 *t) { cout << "do something with Name1*"<<endl; }
...
doMyStuff(n);
doMyStuff(n1);
Run time differentiation:
If you need to decide run time on an arbitrary pointer, you need dynamic run-time type information. The stantard C++ has RTTI for that. But it requires at least one virtual function in the class. So you can't just take any pointer (e.g. void*) and find out what data it points to ! You need a pointer to a valid polymorphic class.
The clean way to do it, would be to make Name and Name1 both inherit from a technical common class with a virtual function:
class vvoid {
virtual void mv() {};
};
Then you can use dynamic_cast and the <typeinfo> to work with the type of your object, and use easily pointers to the base object :
void f(vvoid *p){
cout<<"f("<<p<<"):"<<typeid(*p).name()<< endl;
}
You can then call this function by providing it a pointer to the derived classes:
Name *n=new Name;
Name1 *n1=new Name1;
f(n); // no risk here, it's automatic conversion to base type
f(n1);
Note that for a better design you can also embedd any class specific behaviour in a virtual function, that is specialized for each derived type. But then it's the start of a solid class design, and your assumption was: unrelated classes.
A more error prone approach is to keep each of these classes independent but making sure that each has at least one virtual function, in order to ensure that they are polymorphic and contain RTTI information.
You could then use the dangerous reinterpret_cast and use access to RTTI information. This code demonstrate the principle:
f(reinterpret_cast<vvoid*>(n));
f(reinterpret_cast<vvoid*>(n1));
It seems to work. However, if by accident you'd cast a class that has no virtual function, your code would compile withour warnings but it would awfully stumble at execution.
You can use boost: boost/type_index.hpp. Below you can find code:
#include <boost/type_index.hpp>
#include <iostream>
using std::cout;
using boost::typeindex::type_id_with_cvr;
struct TName
{
};
struct TName1
{
};
int main()
{
TName* name;
cout << "param = " << type_id_with_cvr<decltype(name)>().pretty_name() << '\n';
if (type_id_with_cvr<decltype(name)>().pretty_name() == "TName*")
{
std::cout << "Variant 1\n";
}
TName1* name1;
if (type_id_with_cvr<decltype(name1)>().pretty_name() == "TName1*")
{
std::cout << "Variant 2\n";
}
}
Result:
param = TName*
Variant 1
Variant 2
You can use typeid for this:
string typeToFind == "Name1 *";
if(typeToFind.compare(typeid(Name1).name()) == 0) {
//Your code
}
It may not be pretty, but it does the trick.
This is a sequel to a related post which asked the eternal question:
Can I have polymorphic containers with value semantics in C++?
The question was asked slightly incorrectly. It should have been more like:
Can I have STL containers of a base type stored by-value in which the elements exhibit polymorphic behavior?
If you are asking the question in terms of C++, the answer is "no." At some point, you will slice objects stored by-value.
Now I ask the question again, but strictly in terms of C++11. With the changes to the language and the standard libraries, is it now possible to store polymorphic objects by value in an STL container?
I'm well aware of the possibility of storing a smart pointer to the base class in the container -- this is not what I'm looking for, as I'm trying to construct objects on the stack without using new.
Consider if you will (from the linked post) as basic C++ example:
#include <iostream>
using namespace std;
class Parent
{
public:
Parent() : parent_mem(1) {}
virtual void write() { cout << "Parent: " << parent_mem << endl; }
int parent_mem;
};
class Child : public Parent
{
public:
Child() : child_mem(2) { parent_mem = 2; }
void write() { cout << "Child: " << parent_mem << ", " << child_mem << endl; }
int child_mem;
};
int main(int, char**)
{
// I can have a polymorphic container with pointer semantics
vector<Parent*> pointerVec;
pointerVec.push_back(new Parent());
pointerVec.push_back(new Child());
pointerVec[0]->write();
pointerVec[1]->write();
// Output:
//
// Parent: 1
// Child: 2, 2
// But I can't do it with value semantics
vector<Parent> valueVec;
valueVec.push_back(Parent());
valueVec.push_back(Child()); // gets turned into a Parent object :(
valueVec[0].write();
valueVec[1].write();
// Output:
//
// Parent: 1
// Parent: 2
}
You certainly can't have a polymorphic array (or vector). The requirement that the elements of an array be stored contiguously in memory is fundamentally incompatible with the fact that different derived class types may have different sizes.
None of the standard library containers allow for storing objects of different derived class types in a single container.
Just for fun, based on James's comment about a template-based system, I came up with this Vector-like implementation. It's missing lots of features, and may be buggy, but it's a start!
#include <iostream>
#include <vector>
#include <boost/shared_ptr.hpp>
template <typename T>
class Vector
{
public:
T &operator[] (int i) const { return p[i]->get(); }
template <typename D>
void push_back(D &x) { p.push_back(ptr_t(new DerivedNode<D>(x))); }
private:
class Node
{
public:
virtual T &get() = 0;
};
template <typename D>
class DerivedNode : public Node
{
public:
DerivedNode(D &x) : x(x) {}
virtual D &get() { return x; }
private:
D x;
};
typedef boost::shared_ptr<Node> ptr_t;
std::vector<ptr_t> p;
};
///////////////////////////////////////
class Parent
{
public:
Parent() : parent_mem(1) {}
virtual void write() const { std::cout << "Parent: " << parent_mem << std::endl; }
int parent_mem;
};
class Child : public Parent
{
public:
Child() : child_mem(2) { parent_mem = 2; }
void write() const { std::cout << "Child: " << parent_mem << ", " << child_mem << std::endl; }
int child_mem;
};
int main()
{
Vector<Parent> v;
v.push_back(Parent());
v.push_back(Child());
v[0].write();
v[1].write();
}
First of all, your requirements are still not perfectly clear. I will assume that you want "inline storage" for the container; so, for example, in a "polymorphic" vector, all elements would be adjacent in memory (with only padding in between as needed for correct alignment).
Now, it is possible if you're willing to provide an exhaustive list of all types that you're going to put into the container at compile-time. The most straightforward implementation would be to use a union of all possible types as the type of the backing array - that would ensure enough size and proper alignment, and same O(1) access by index, at the cost of some wasted space on elements of smaller-size types. I can go into this with more detail if you want.
If the list of types is now known in advance, or if you do not want that kind of overhead, then you'd have to maintain a separate index of pointers (or offsets from the beginning of the backing store) to elements, so that you can do O(1) access. Also, given the alignment issues, I'm not sure if you could even do that in fully portable C++03, though you definitely can in C++0x.