Duplicating subclass of abstract baseclass - c++

I have an abstract base-class to enforce some subclasses to overload the << operator.
I am storing a bunch of pointers to instances of these subclasses in an std::stack... At some point I wish to duplicate the top item of the stack (and push it on top).
The problem is, I cannot instantiate an abstract class. And obviously since I want to do this for each of my subclasses, I won't know the type...
I wonder if this is even possible without adding another pure virtual method (say 'Base *clone() = 0') and implement it in each of my subclasses? Surely there must be a cleaner way.

I think you actually need a Clone method in this case. You want to dynamically copy the subclass item at runtime, and the normal way to change behavior at runtime is virtual methods. Without using some virtual method you would have no way of figuring out which child it is. You could probably use CRTP to automatically generate that Clone for you though:
// Totally uncompiled and untested.
class Base
{
public:
virtual Base* Clone() const = 0;
};
template <class T>
class Child : public Base
{
public:
virtual Base* Clone() const { return new T(*static_cast<T*>(this)); }
protected:
Child(); // Can't instantiate directly
Child(const Child& right); // Can't instantiate directly
};
class Grandchild : public Child<Grandchild>
{
// Clone should do the right thing.
};

Do you mean making a copy of the class, rather than duplicating the pointer.
You will need to either implement your own typing. in other words have a virtual function that returns the class type and then create the appropriate class
Or enable RTTI (Run-Time Type Information) to do the same thing. because RTTI effects every class its possibly more efficient to create your own typeof method.
Then you can
Pop the pointer
Get the type
Instantiate the correct class using
a copy constructor probably in a
switch
Push both back onto the stack
psuedocode
base* ptr = stack.pop()
base *copy
switch (ptr->typeof()) {
case class1type : copy = new class1(ptr) break;
case class2type : copy = new class2(ptr) break;
...
}
stack.push (ptr)
stack.push(copy)
DC

Related

Copy contents of unique_ptr to unknown derived class

I have an abstract base class, with several concrete derived classes; none of these classes manage any resources.
#include <memory>
#include <vector>
// this is a pure abstract class that contains no resources
class Base {
public:
Base() {};
virtual int doSomething() = 0;
};
class Derived : public Base {
public:
Derived() {};
// this mutates the derived class
int doSomething() override { return 0; };
};
class Derived2 : public Base {
public:
Derived2() {};
// this mutates the derived class
int doSomething() override { return 0; };
};
and I have a function that returns a random derived instance (Derived1, Derived2, Derived3, depending upon a random number throw).
std::unique_ptr<Base> randomDerivedInstance() {
// pick a random number here and return Derived1 or Derived2 etc.
// for the purpose of this problem, I'm just returning a fixed derived class
return std::make_unique<Derived>();
}
and I have a struct that I want to store this derived instance in
struct DataStruct {
// this can contain Derived1 or Derived2
std::unique_ptr<Base> base;
// other things in struct omitted for clarity
// obviously this won't work
DataStruct(std::unique_ptr<Base> base) : base(base) {};
};
I return a unique pointer from my random function, and want to save a copy into the struct, and then call doSomething on it that performs several mutating operations on the class internals, and I don't want them to affect the copy stored in the list.
If I knew the type of the derived instance, I would use a copy constructor to create a new instance and add it to the vector, but in this situation I don't know the specific type of the instance I'm trying to add, so I don't know which specific constructor to use.
int main() {
// I want to create a vector of random instances
std::vector<DataStruct> list;
// I create a random instance
auto myDerived = randomDerivedInstance();
// and I want to push a copy of myDerived before I do something with it
// obviously this doesn't work because its a unique_ptr
// what can I do here?
list.push_back(DataStruct(myDerived));
// do something that mutates myDerived
myDerived->doSomething();
// I don't want my mutations to myDerived to affect the list copy
}
The code above doesn't compile for obvious reasons since I'm trying to assign a unique_ptr in the DataStruct constructor.
What changes do I need to make to this architecture and code in order to get this to work as intended? i.e. add a value-copy of random derived instance to a struct, so that I can mutate the original instance (or vice-versa, add original, and mutate copy).
Thanks for all help in advance!
In class Base add a virtual member function clone:
virtual auto clone() const
-> std::unique_ptr<Base>
= 0;
In each derived class Derived override that to provide a derived class specific clone:
auto clone() const
-> std::unique_ptr<Base>
override
{ return std::unique_ptr<Base>( new Derived{ *this } ); }
It's possible to do this in a more advanced way where if you know the most derived class at compile you can get a clone statically of that type, but it doesn't appear that you need that.
Disclaimer: off-the-cuff code, not reviewed by compiler.
At one time, long ago, a clone function was called a virtual constructor, and that term is used in the FAQ item about this. I think it was introduced by Coplien. The current FAQ text doesn't say.
Also worth noting: in C++11 and later the generation of clone function implementations can be partially automated by Derived inheriting from an implementation that in turn inherits from Base, with forwarding of constructor arguments.
C++03 didn't support forwarding so then one had to use schemes such as code-generating macro (evil but in practice the only real solution back then), implementation inheritance via dominance in a virtual inheritance hierarchy (extremely complex and ugly), or to do the same as we now can do in C++11 and later, but with a Do-It-Yourself argument forwarding scheme (somewhat arbitrary limited).
For an overview of these old C++03 techniques see my 2010 blog article “3 ways to mix in a generic cloning implementation”.

inheritance of an implemented class

This is probably a simple question, please bear with me since I'm used to Java...
Lets say we have an interface:
class IDoable {
virtual void do() = 0;
};
Another class:
class Base : public IDoable {
//...
virtual void do() { ... }
};
And a last class extending our base class:
class ExtendingBase : public Base {
// some extra functionality
};
I am lost at the part if I want to make a list of IDoable objects, which can be Base objects or ExtendingBase objects. Do I have to add some method declaration of the methods in the Base class? How does this aspect work?
EDIT:
I have someList of type IDoable pointers
and if I then try to add a Base object to that list I get the error:
IDoable is an ambiguous base of Base
Same if i try to add an ExtendingBase object
IDoable is an ambiguous base of ExtendingBase
Since do is a pure virtual method, it will have to be implemented in a derived class. You can't have a vector or array of IDoable objects because you can't instantiate such an object. You can have a vector or array of pointers or references to objects though.
If you create an ExtendingBase object and call the do function, it will call the Base class' one (since ExtendingBase inherits that method).
Virtual polymorphism enters into play when you call the do() function from a base class pointer or reference: the do() function appropriate to the dynamic type of the object pointed or referenced to will be called:
class IDoable{
public:
virtual void dof()=0;
virtual ~IDoable() = default;
};
class Base:public IDoable{
public:
virtual void dof(){std::cout << "Base";}
virtual ~Base() = default;
};
class ExtendingBase:public Base{
public:
virtual void dof() { std::cout << "ExtendingBase"; }
};
int main()
{
IDoable *ptr = new Base(); // A smart pointer would be a better choice
// but for clarity's sake I'm using bare
// memory allocations here
ptr->dof(); // Walks the virtual table and calls "Base"
delete ptr;
ptr = new ExtendingBase();
ptr->dof(); // Walks the virtual table and calls "ExtendingBase"
delete ptr;
}
Also notice the use of virtual destructors: they work like normal virtual functions and thus when calling delete on a base pointer, in order to actually destruct the right type of object (i.e. to call the right destructor in the hierarchy), you will need to make it virtual.
As a sidenote: do is a reserved keyword in C++
In response to your edit: if you have a vector or a list of IDoable pointers, you can't just add a derived object to it, but you should add a pointer to a derived object. I.e. the following is wrong:
std::vector<IDoable*> vec;
vec.push_back(Base());
plus a base class remains a class (there is no interface concept in C++ as in Java) and you shouldn't inherit from a base class multiple times:
class Base:public IDoable{
...
class ExtendingBase:public Base, public IDoable <- nope
...
that would only cause issues in identifying the base subobject.
I recommend to read about the dreaded diamond problem in C++ (it's a way to solve a base class appearing multiple times in the inheritance hierarchy.. anyway a good design might probably avoid this in the first place).
if I want to make a list of IDoable objects
You cannot make an IDoable object period. It's an abstract class, it cannot be constructed directly, so you cannot have a container of them. What you can do and what you likely intend is to have a container of IDoable*:
std::vector<IDoable*> objects;
objects.push_back(new Base);
objects.push_back(new ExtendedBase);
Or to express ownership better in C++11:
std::vector<std::unique_ptr<IDoable>> objects;
Given your interface, you can already call do() on any of these objects and that will do the right thing via virtual dispatch. There is one member function you definitely want to add to your interface though:
class IDoable {
public:
virtual ~IDoable() = default; // this one
virtual void do() = 0;
};
That way, when you delete an IDoable*, you will delete the full object, not just the base interface.
You will have to implement your do() function in Base, since the function in the class IDoable is pure virtual.
If you decide to create an ExtendingBase object, the do() function will behave as it's implemented in Base, unless you override it by re-implementing it in ExtendingBase.
the first and most major of your problem is that your thinking in Java.
the words "interface" and "extending" are very Java oriented. C++ does not think this way.
for example, when someone talks about an "interface" in a C++ context, I may think he talks about the class decleration inside the .h file (as opposed to the implementation which lies in the .cpp file)
IDoable is a CLASS. period. the only difference is that it has a pure virtual functions that prohibits instansiation. other than that it behaves as a class, it can be inherited from, can hold member variables and anything else.
you just need to make sure the abstract function is overriden in some derived class in order for that class to produce objects.
thus said :
//in the stack:
Base base;
ExtendingBase eBase;
base.do();
eBase.do()
//in the heap with IDoable as pointer:
IDoable * base = new Base();
IDoable * ebase = new ExtendingBase ();
base->do();
ebase->do();
now, you may ask - how do I activate Base and ExtendingBase functions? so just like Java, you need to cast the pointer and only then call the right function.
Base* realBase = (Base*)base;
realbase->someBaseFunction();
as many things in C++, this code is a bit dangerous. you can use dynamic_cast instead.
and one last thing - do is a keyword in C++, it cannot declare a function name.
IDoable *pDo1 = new Base();
IDoable *pDo2 = new ExtendingBase();
pDo1->do();
pDo2->do();
delete pDo1;
delete pDo2;

C++ copy constructor issue with parent/child classes

I've run into a problem with copy constructors...I assume there is a basic answer to this and I'm missing something obvious - maybe I'm doing something entirely wrong - but I haven't been able to figure it out.
Basically, I have a parent class and child class. The parent class contains a vector of pointers to a (different) base class object. The child class wants to instead store pointers to objects derived from that base object.
Here's a pseudocode sample, if that helps:
// Base classes
class ItemRev {
...
}
class Item {
protected:
vector<ItemRev *> m_revPtrVec;
}
Item::Item(const Item &inputItemObj)
{
// Copy contents of the input object's item rev pointer vector
vector<ItemRev *>::const_iterator vecIter = (inputItemObj.m_revPtrVec).begin();
while (vecIter != (inputItemObj.m_revPtrVec).end()) {
(this->m_revPtrVec).push_back(new ItemRev(**vecIter));
}
}
=========
// Derived classes
class JDI_ItemRev : public ItemRev {
...
}
class JDI_Item : public Item {
...
}
JDI_Item::JDI_Item(const JDI_Item &itemObj)
{
// Copy contents of the input object's item rev pointer vector
vector<ItemRev *>::const_iterator vecIter = (inputItemObj.m_revObjPtVec).begin();
// The below does not work!
while (vecIter != (inputItemObj.m_revObjPtVec).end()) {
m_revObjPtVec.push_back(new JDI_ItemRev(**vecIter));
}
}
The problem with the above is in the push_back() call in the JDI_Item copy constructor.
Given this setup, what should the child class's copy constructor look like? Do I even need a child class copy constructor? I assumed I did, because the copy constructor is creating new objects, and the parent copy constructor will create new objects that are not the type I want in the derived class (i.e., the parent object stores pointers to ItemRev objects, while the child object should store pointers to derived JDI_ItemRev objects).
As mentioned in the comments, there is probably a more succinct way to express this problem (i.e. your class structure needs some work).
However, if you want to do it this way, the easiest way to achieve it is to use a virtual clone() method in the base class of ItemRev, with overrides of it defined in derived classes.
e.g.:
class ItemRev {
virtual ItemRev* clone() const = 0;
};
class JDI_ItemRev : public ItemRev {
ItemRev* clone() const override
{
// do your actual cloning here, using the copy constructor
return new ItemRev(*this);
}
};
Now, whenever you call clone() on any class derived from ItemRev, you will be returned an ItemRev* but it will point to a fully constructed derived class. You can of course get to the derived class's interface with static_cast<> or dynamic_cast<>.
...however...
derivation often seems like an easy win but it often turns out not to be. Inheritance should only be used if the derived class really is a type of the base class. Often people select inheritance when the derived class is a lot like a base class, or shares many characteristics with a base class. This is not the time to use inheritance. It's the time to use encapsulation.
In general, inheritance is evil.
On another note, you might find this link interesting.
Presentation on inheritance as an implementation detail

Is there a way to infer the type of an object?

This may be a stupid question, I suspect I know the answer (no) because I seem to be hitting a wall here.
Given I have a collection of objects derived from certain class:
class BaseClass;
class DerivedA: public BaseClass;
class DerivedB: public BaseClass;
class DerivedC: public BaseClass;
std::vector<BaseClass> myCollection;
I want to call a method depending on the types of the specific class:
class Processor {
void doSomething(DerivedA a, DerivedB b);
void doSomething(DerivedA a, DerivedC c);
}
The problem is, if I access the individual items on the collection and try to call the 'doSomething' method in the 'Processor', it will not be able do decide which method to use (afaik). So my question is: Is there any way to fetch the items in the collection with the right derived-type?
If you are going to keep the doSomething method as it is, this is what is called multiple dispatch and is NOT currently supported by C++.
If it were a virtual member function of BaseClass then yes it would be the run of the mill C++ polymorphism on the object it is being invoked on, but it would still NOT automatically infer the type of the arguement.
To get around this you can do something like what is suggested in the earlier link
void collideWith(Thing& other) {
// dynamic_cast to a pointer type returns NULL if the cast fails
// (dynamic_cast to a reference type would throw an exception on failure)
if (Asteroid* asteroid = dynamic_cast<Asteroid*>(&other)) {
// handle Asteroid-Asteroid collision
} else if (Spaceship* spaceship = dynamic_cast<Spaceship*>(&other)) {
// handle Asteroid-Spaceship collision
} else {
// default collision handling here
}
}
Basically keep casting to various possible Derived classes until one works and call one of the methods appropriately(no special effort since the compiler knows what type you are trying to cast to).
IMPORTANT: as #WhozCraig points out, your vector needs to hold pointers to avoid Object-Slicing and render this whole question moot.
Ok, yes you should use polymorphism as the above stated. If your function needs to handle 2 objects though it gets extremely complicated.
If the derivations form a limited set and know each other you can use double-dispatch. It's not perfect but it solves this particular case.
class DerivedA;
class DerivedB;
class DerivedC;
class BaseClass
{
public:
virtual ~BaseClass();
virtual void doSomethingWithBase( BaseClass & b2 ) = 0;
virtual void doSomethingWithDerivedA( DerivedA & da ) = 0;
virtual void doSomethingWithDerivedB( DerivedB & db ) = 0;
virtual void doSomethingWithDerivedC( DerivedC & dc ) = 0;
};
class DerivedA : public BaseClass
{
public:
void doSomethingWithBase( BaseClass & b2 )
{
b2.doSomethingWithDerivedA( *this );
}
void doSomethingWithDerivedA( DerivedA & da )
{
// implement for two DerivedA objects
}
void doSomethingWithDerivedB( DerivedB & db )
{
// implement for an A and B
}
void doSomethingWithDerivedC( DerivedC & dc )
{
// implement for an A and C
}
};
// implement DerivedB to call doSomethingWithDerivedB on its parameter
// implement DerivedC to call doSomethingWithDerivedC on its parameter.
You get the idea. From where you call you don't need to know which two types you have and you never need to actually look this up. But if you ever add more implementations you have a lot of code to edit and may consider some kind of lookup table.
If you need a class to define itself you can use some kind of virtual id.
class BaseClass
{
public:
virtual int id() const = 0;
};
and then you get the classes to reveal their ids and find the handler in the table based on these ids that wil handle the two objects. The ids don't have to be ints, they can be strings which makes it easier to avoid naming clashes, and this has the advantage over the double-dispatch method of the base class not knowing its derived classes or them knowing each other, and being extensible. You also don't have to handle every pair.

Polymorphism and checking if an object has a certain member method

I'm developing a GUI library with a friend and we faced the problem of how to determine whether a certain element should be clickable or not (Or movable, or etc.).
We decided to just check if a function exists for a specific object, all gui elements are stored in a vector with pointers to the base class.
So for example if I have
class Base {};
class Derived : public Base
{
void example() {}
}
vector<Base*> objects;
How would I check if a member of objects has a function named example.
If this isn't possible than what would be a different way to implement optional behaviour like clicking and alike.
You could just have a virtual IsClickable() method in your base class:
class Widget {
public:
virtual bool IsClickable(void) { return false; }
};
class ClickableWidget : public Widget
{
public:
virtual bool IsClickable(void) { return true; }
}
class SometimesClickableWidget : public Widget
{
public:
virtual bool IsClickable(void);
// More complex logic punted to .cc file.
}
vector<Base*> objects;
This way, objects default to not being clickable. A clickable object either overrides IsClickable() or subclasses ClickableWidget instead of Widget. No fancy metaprogramming needed.
EDIT: To determine if something is clickable:
if(object->IsClickable()) {
// Hey, it's clickable!
}
The best way to do this is to use mixin multiple inheritance, a.k.a. interfaces.
class HasExample // note no superclass here!
{
virtual void example() = 0;
};
class Derived : public Base, public HasExample
{
void example()
{
printf("example!\n");
}
}
vector<Base*> objects;
objects.push_back(new Derived());
Base* p = objects[0];
HasExample* he = dynamic_cast<HasExample*>(p);
if (he)
he->example();
dynamic_class<>() does a test at runtime whether a given object implements HasExample, and returns either a HasExample* or NULL. However, if you find yourself using HasExample* it's usually a sign you need to rethink your design.
Beware! When using multiple inheritance like this, then (HasExample*)ptr != ptr. Casting a pointer to one of its parents might cause the value of the pointer to change. This is perfectly normal, and inside the method this will be what you expect, but it can cause problems if you're not aware of it.
Edit: Added example of dynamic_cast<>(), because the syntax is weird.
If you're willing to use RTTI . . .
Instead of checking class names, you should create Clickable, Movable, etc classes. Then you can use a dynamic_cast to see if the various elements implement the interface that you are interested in.
IBM has a brief example program illustrating dynamic_cast here.
I would create an interface, make the method(s) part of the interface, and then implement that Interface on any class that should have the functionality.
That would make the most sense when trying to determine if an Object implements some set of functionality (rather than checking for the method name):
class IMoveable
{
public:
virtual ~IMoveable() {}
virtual void Move() = 0;
};
class Base {};
class Derived : public Base, public IMoveable
{
public:
virtual void Move()
{
// Implementation
}
}
Now you're no longer checking for method names, but casting to the IMoveable type and calling Move().
I'm not sure it is easy or good to do this by reflection. I think a better way would be to have an interface (somethign like GUIElement) that has a isClickable function. Make your elements implement the interface, and then the ones that are clickable will return true in their implementation of the function. All others will of course return false. When you want to know if something's clickable, just call it's isClickable function. This way you can at runtime change elements from being clickable to non-clickable - if that makes sense in your context.