Hello to everyone.
I would like to create a general function that is able to print some info that come from different kinds of objects.
There are at least two different situations: in the first one I receive a shared pointer (AddElementTypeA, AddElementTypeB), in the second one I receive an object and I want to create a shared pointer with that (AddElementTypeC).
In particular, in the second case I want to allocate a new area of memory, copy the content and set the shared pointer on that area. I thought the copy constructor could be useful in this sense, but my solution doesn't work.
Below you can find the code I wrote, can you help me to understand why it doesn't work?
y.data = std::make_shared<ObjC>( tmp );
// is same as:
std::shared_ptr<ObjC> foo( new ObjC(tmp) );
y.data = foo;
A new ObjC object is copy-constructed, initialized with value of 'tmp', in dynamically allocated memory.
A shared-pointer object is contructed and initialized the address of the new ObjC object.
Then you copy-assign the shared-pointer to y.data.
Therefore, the y.data points to object in dynamic memory, which does not die at end of the function, like the function-local automatic variable 'tmp'.
Rather than having ExportManager::PrintElement() figure out what to do, add a virtual method to the objects that does it. That means each object should inherit from a base class.
Since each object has a name, it makes sense to put the name in the base class too.
In well designed software, each function or method does one thing. Also, your methods shouldn't "do the work." Instead they should "make doing the work easy." If you think this way then you'll end up with more flexible software.
For example, ExportManager::PrintElement() shouldn't delete x because printing and deleting are very different things. If the caller wants to print and delete, then they can do it in two steps.
Similarly, you should have just one Add() method that adds shared_ptr<Base>. If the caller has an object to add instead of a pointer, then they can make the shared pointer themselves.
Thanks for the suggestion, but unfortunately I cannot do that, because what I called ObjA, ObjB and ObjC are objects that I receive and they have nothing in common. Furthermore, I cannot change those objects so I cannot create a base class.
Because of that, I'm trying to use the std::static_pointer_cast<void>() solution.
The idea is to have a vector in which I can put inside different kinds of elements that have nothing in common. As you can imagine I cannot use the inheritance features.
Do you know if this is a good solution of if there are better and more safe?
You could use multiple inheritance. Something like this with my original idea:
1 2 3 4 5 6 7 8 9 10 11 12 13
class Base {
virtualvoid print();
};
class MyObjA : public Base, public ObjA {
virtualvoid print();
};
class MyObjB : public Base, public ObjB {
virtualvoid print();
};
class MyObjC : public Base, public ObjC {
virtualvoid print();
};