I am trying to refactor some code while leaving existing functionality in tact. I'm having trouble casting a pointer to an object into a base interface and then getting the derived class out later. The program uses a factory object to create instances of these objects in certain cases.
Here are some examples of the classes I'm working with.
// This is the one I'm working with now that is causing all the trouble.
// Some, but not all methods in NewAbstract and OldAbstract overlap, so I
// used virtual inheritance.
class MyObject : virtual public NewAbstract, virtual public OldAbstract { ... }
// This is what it looked like before
class MyObject : public OldAbstract { ... }
// This is an example of most other classes that use the base interface
class NormalObject : public ISerializable
// The two abstract classes. They inherit from the same object.
class NewAbstract : public ISerializable { ... }
class OldAbstract : public ISerializable { ... }
// A factory object used to create instances of ISerializable objects.
template<class T> class Factory
{
public:
...
virtual ISerializable* createObject() const
{
return static_cast<ISerializable*>(new T()); // current factory code
}
...
}
This question has good information on what the different types of casting do, but it's not helping me figure out this situation. Using static_cast and regular casting give me error C2594: 'static_cast': ambiguous conversions from 'MyObject *' to 'ISerializable *'. Using dynamic_cast causes createObject() to return NULL. The NormalObject style classes and the old version of MyObject work with the existing static_cast in the factory.
Is there a way to make this cast work? It seems like it should be possible.
You have to virtually inherit from ISerializable (I just tested it with VS2010). This is a common issue called the Diamond Problem, where the compiler does not know wich hierarchy path to take.
EDIT:
This should do it:
class NewAbstract : public virtual ISerializable { ... }
class OldAbstract : public virtual ISerializable { ... }
You can get round it by casting to one of your immediate bases first eg.
virtual ISerializable* createObject() const
{
NewAbstract*const na = dynamic_cast< NewAbstract* >( new T() );
return dynamic_cast< ISerializable* >( na );
}
Don't inherit virtually from both NewAbstract and OldAbstract. Pick one to inherit virtually from. I think that may take care of it.
Look up "dreaded diamond" and virtual inheritance. They may help you.
Related
I have been struggling with this kind of problem for a long time, so I decided to ask here.
class Base {
virtual ~Base();
};
class Derived1 : public Base { ... };
class Derived2 : public Base { ... };
...
// Copies the instance of derived class pointed by the *base pointer
Base* CreateCopy(Base* base);
The method should return a dynamically created copy, or at least store the object on stack in some data structure to avoid "returning address of a temporary" problem.
The naive approach to implement the above method would be using multiple typeids or dynamic_casts in a series of if-statements to check for each possible derived type and then use the new operator.
Is there any other, better approach?
P.S.: I know, that the this problem can be avoided using smart pointers, but I am interested in the minimalistic approach, without a bunch of libraries.
You add a virtual Base* clone() const = 0; in your base class and implement it appropriately in your Derived classes. If your Base is not abstract, you can of course call its copy-constructor, but that's a bit dangerous: If you forget to implement it in a derived class, you'll get (probably unwanted) slicing.
If you don't want to duplicate that code, you can use the CRTP idiom to implement the function via a template:
template <class Derived>
class DerivationHelper : public Base
{
public:
virtual Base* clone() const
{
return new Derived(static_cast<const Derived&>(*this)); // call the copy ctor.
}
};
class Derived1 : public DerivationHelper <Derived1> { ... };
class Derived2 : public DerivationHelper <Derived2> { ... };
An alternative is to have a pure virtual CreateCopy() method in the common base that is implemented in each derived class.
In C++, does inheriting a common ancestor and inheriting an interface (and requiring definition of a method in derived classes) require multiple inheritance? Eg. do I have to do the following (instead of merging MyInterface and ParentClass):
class MyInterface;
class ParentClass;
class DerivedClass1;
class DerivedClass2;
class SomeOtherType;
class YetAnotherType;
class MyInterface {
public:
// Must be defined in all derived classes
virtual SomeOtherType my_common_fxn(...) = 0;
...
};
class ParentClass {
private:
// Common ancestor
YetAnotherType _useful_member;
}
class DerivedClass1 : MyInterface, ParentClass {
public:
// Do some things with _useful_member, using approach #1
SomeOtherType my_common_fxn(...);
...
}
class DerivedClass2 : MyInterface, ParentClass {
public:
// Do some things with _useful_member, using approach #2
SomeOtherType my_common_fxn(...);
...
}
void fxn_or_method_using(ParentClass);
Is it possible to (elegantly) merge the functionality of MyInterface and ParentClass into a single class? (I believe that as MyInterface is an ABC I cannot use this type as a parameter to fxn_or_method_using.)
Apologies in advance if this is a duplicate- I've searched but none of the existing C++ questions appeared to line up. Q's and/or A's may have been over my (untrained) head.
There's nothing wrong with your inheritance model.
But in C++ you need a pointer or reference for polymorphism. Your fxn_or_method_using takes its parameter by value. That has several problems. It causes slicing, it prevents polymorphic function calls, and it can't work for an abstract type because you can't create instances of those.
If you change fxn_or_method_using to take its parameter by reference not value, then you can declare it as referring to MyInterface if you wish. All the disadvantages disappear and you get the polymorphic behaviour you want.
No. You can mix virtual and pure virtual and concrete inheritance all from the same class in C++ with no problems.
class baseClass{
public:
blah1(){
//stuff
}
virtual blah2();
virtual blah3() = 0;
};
class derivedClass : baseClass
{
};
I am facing problems about class inheritance design. It is shown in C++ as follows:
There are 2 kinds of classes, we call them Object and Component first.
Class Object uses class Component, but problem occurs with their subclasses.
For simple, there are 6 classes.
class BaseComponent{...};
class ComponentA: public BaseComponent{...};
class ComponentB: public BaseComponent{...};
class BaseObject {
public:
virtual bool doSomething()=0;
void setBaseComponent(BaseComponent*c){_c = c;}
BaseComponent* getBaseComponent() {return _c;}
private:
BaseComponent* _c;
}
class ObjectA : public BaseObject {
public:
bool doSomething(){ /*do someting related to ComponentA*/}
void setComponentA(ComponentA* a) {setBaseComponent(a);}
ComponentA* getComponentA()
{return static_cast<ComponentA*>(getBaseComponent());}
}
class ObjectB : public BaseObject {
public:
bool doSomething(){ /*do someting related to ComponentB*/}
void setComponentB(ComponentB* b) {setBaseComponent(b);}
ComponentB* getComponentB()
{return static_cast<ComponentB*>(getBaseComponent());}
}
Now the problem comes:
If I do like the above code, I have to check always the class relationship.
(for example, I have to check real class in ObjectB::getComponentB() when use static_cast)
If I change the code and use ComponentA directly in ObjectA, I'm abandoning the "Dependency inversion", which makes the code not convenient.
So, could anyone give me some advice?
So any subclass of BaseObject always needs the matching BaseComponent subclass?
Make the setter in BaseObject protected. It claims that you can give any object any component, and that's a promise the subclasses can't uphold if anyone but them has access to that setter.
Even better would be to make the component a constructor argument, if that's at all possible.
The idea of using interfaces instead of concrete classes is that when you use a pointer of the interface you do not have to worry about what is behind.
If you are returning the concrete ComponentA and ComponentB then you lose that.
Then, IMO, you should change these concrete classes to be able to return a pointer of BaseComponent and then you will not need the static_cast.
After writing a test, I determined that the this pointer in an interface is not equal to the this pointer of the concrete class, meaning I can't just use a C-style cast on it.
class AbstractBase {...};
class AnInterface {
public:
AnInterface() {...} // need AbstractBase * here
~virtual AnInterface() {...} // and here
};
class Concrete : public AbstractBase, public AnInterface {};
My interface needs a base class pointer to the concrete class inheriting it in the constructor and destructor in order to handle interface related registration and deregistration.
Every concrete object that inherits the interface needs to inherit the abstract base class first, it is always first in the layout.
For the constructor it is not all that hard, I can add a pointer in the interface constructor and pass this from the concrete class. But the destructor doesn't have any parameters, so I am in the dark there.
The solutions I came up with so far come with overhead:
1 - store the pointer in the interface to be used in the destructor - adds in one pointer worth of memory overhead
class AnInterface {
public:
AnInterface(AbstractBase * ap) {...}
~virtual AnInterface() {...} // and here
private:
AbstractBase * aPtr;
};
...
Concrete() : AnInterface(this) {}
2 - create an abstract method in the interface and implement it to return this in the concrete class - adds in the overhead of indirection for the virtual call
class AnInterface {
virtual AbstractBase * getPtr() = 0;
};
class Concrete : public AbstractBase, public AnInterface {
AbstractBase * getPtr() { return this; }
};
3 - dynamic_cast is even worse
Is there a more efficient way to achieve this?
IMO if decoupling between the base class and the interface is really needed, both solution 1 and 2 have tolerable overheads, certainly nothing that will be a problem on contemporary hardware.
But since you say that the interface is designed to work with the functionality, provided in the base class, then maybe the decoupling is not a good thing.
I mean if the problem is with inheriting multiple interfaces which all inherit the base class, or the "dreaded diamond" problem with inheritance, you can simply use virtual inheritance.
All of your concerns seem like micro-optimizations. Assuming you truly can't separate out your interface from your implementation (in which case, why are you using interfaces in the first place?) I would just use dynamic_cast and be done with it, even though it's pretty heavyweight. If I were stuck on a platform where RTTI isn't an option then I'd use option 2.
Your design has some flaws.
You should consider using CRTP as from the Mixin aspect, which saves you from keeping an extra pointer of the concrete derived.
template<typename Derived>
class AnInterface {
public:
AnInterface() {
Derived* derived = static_cast<Derived*>(this);
AbstractBase* abstractBase = static_cast<AbstractBase*>(derived);
} // have AbstractBase * here
~virtual AnInterface() {...} // and here
};
class Concrete
: public virtual AbstractBase
, public AnInterface<Concrete> {
AbstractBase * getPtr() { return this; }
};
I have been struggling with this kind of problem for a long time, so I decided to ask here.
class Base {
virtual ~Base();
};
class Derived1 : public Base { ... };
class Derived2 : public Base { ... };
...
// Copies the instance of derived class pointed by the *base pointer
Base* CreateCopy(Base* base);
The method should return a dynamically created copy, or at least store the object on stack in some data structure to avoid "returning address of a temporary" problem.
The naive approach to implement the above method would be using multiple typeids or dynamic_casts in a series of if-statements to check for each possible derived type and then use the new operator.
Is there any other, better approach?
P.S.: I know, that the this problem can be avoided using smart pointers, but I am interested in the minimalistic approach, without a bunch of libraries.
You add a virtual Base* clone() const = 0; in your base class and implement it appropriately in your Derived classes. If your Base is not abstract, you can of course call its copy-constructor, but that's a bit dangerous: If you forget to implement it in a derived class, you'll get (probably unwanted) slicing.
If you don't want to duplicate that code, you can use the CRTP idiom to implement the function via a template:
template <class Derived>
class DerivationHelper : public Base
{
public:
virtual Base* clone() const
{
return new Derived(static_cast<const Derived&>(*this)); // call the copy ctor.
}
};
class Derived1 : public DerivationHelper <Derived1> { ... };
class Derived2 : public DerivationHelper <Derived2> { ... };
An alternative is to have a pure virtual CreateCopy() method in the common base that is implemented in each derived class.