C++ Polymorphism: from parent class to child [duplicate] - c++

This question already has answers here:
When should static_cast, dynamic_cast, const_cast, and reinterpret_cast be used?
(11 answers)
Closed 8 years ago.
In C++ we can convert child class pointer to parent, but is there any way to convert it back: from parent, which was obtained from child, give child class back?
I mean:
class Parent
{
...
};
class Child : public Parent
{
...
};
int main(int argc, char const *argv[])
{
Child* child = new Child();
Parent* parent = child;
Child* old_child = parent; // how to do this??
return 0;
}
Thank you for your answers.

"but is there any way to convert it back: from parent, which was obtained from child, give child class back?"
Yes, as mentioned in the other answers, there are two ways to do this.
Child * old_child = dynamic_cast<Child*>(parent);
The result of the dynamic_cast<> can be checked at runtime, thus you can determine if the parent object really represents a Child instance:
if(!old_child) {
// parent is not a Child instance
}
Also note to get this working properly, the classes in question need to have a vtable, that RTTI can actually determine their relation. The simplest form to achieve this, is giving the Parent class a virtual destructor function
class Parent {
public:
virtual ~Parent() {}
// or
// virtual ~Parent() = default;
// as suggested for latest standards
};
NOTE:
If this should apply to a general design decision, I would strongly disregard it. Use pure virtual interfaces instead, that are guaranteed to be implemented, or not.
The second way of static_cast<> can be used in environments, where you well know that parent actually is a child. The simplest form of this is the CRTP, where Parent takes the inheriting class as a template parameter
template <class Derived>
class Parent {
void someFunc() {
static_cast<Derived*>(this)->doSomething();
}
};
class Child : public Parent<Child> {
public:
void doSomething();
};
The validity of an instatiation of Parent<> and static_cast<> will be checked at compile time.
NOTE:
Another advantage is that you can use an interface for derived that makes use of
static class members of Derived
typedef's provided by Derived
... more class traits, that can be checked at compile time

You need to cast the object back to child. This is done like this:
Child * old_child = static_cast<Child*>(parent);
and
Child * old_child = dynamic_cast<Child*>(parent);

int main() {
Parent parent;
Child child;
// upcast - implicit type cast allowed
Parent *pParent = &child;
// downcast - explicit type case required
Child *pChild = (Child *) &parent;
}
You should use the dynamic_cast to do this safely:
Child *p = dynamic_cast<Child *>(pParent)
EDIT
With dynamic_cast returns a null pointer if the type is not apart of the base class, also casting to a reference throws a bad_cast exception. dynamic_cast is particularly useful if you do not know what the object type will be.
On the other hand static_cast:
Child *p = static_cast<Child *>(pParent)
This assumes that you want to reverse an explicit conversion and perform no runtime checks. This allows for flexibility but must be used with caution.
The regular downcast shown above:
Child *pChild = (Child *) &parent;
Is a C-style down cast (like a static_cast), which may also cast to a private base class (not sure about, multiple inheritance), while static_cast would cause a compile-time error. Things like numeric conversions is a good example to use this on.

Above answers are good, conceptually you can think like this,
Your Car object which is derived from Vehicle class. You can refer Car as Vehicle, and can convert to Car as it originally belonged to Car. But it will be a problem if your Vehicle object actually representing Bike and trying to convert to Car. Thats why you need safe casting.
class Vehicle
{
...
};
class Car : public Vehicle
{
...
};
class Bike : public Vehicle
{
...
};
int main(int argc, char const *argv[])
{
Vehicle* vehicle = new Car();
Car* old_car = dynamic_cast<Car *>(vehicle);
if(old_car) {
// OK Vehicle is Car, use it
}
vehicle = new Bike();
old_car = dynamic_cast<Car *>(vehicle);
if(old_car) {
// No Vehicle isn't Car, this code won't execute
}
return 0;
}

Related

Move assignment operator in subclass not being called / inherited

I've got a simple base class and two classes that inherit from it. The problem is that the move assignment operators in each of the child classes aren't being used. Here's basically what I have:
class Parent {
public:
virtual ~Parent();
virtual Parent& operator=(Parent &&parent);
};
class Child1 : public Parent {
public:
~Child1();
Child1& operator=(Child1 &&child);
};
class Child2 : public Parent {
public:
~Child2();
Child2& operator=(Child2 &&child);
};
The implementations are littered with logs, so I know what's being called and when. Then, I run this (pseudo)code:
Parent &p {};
if (x == 1)
p = Child1 {};
else
p = Child2 {};
And I get output that looks something like this:
: Child constructor
: Parent move operator
: Child destruct
: SIGSEGV
Any idea what I'm doing wrong?
This is a classic case of slicing where you are assigning an instance of a derived type to an instance of a base type. To fix this you have to use dynamic allocation and pointers:
std::unique_ptr<Parent> p;
if(x == 1)
p = std::make_unique<Child1>();
else
p = std::make_unique<Child2>();
C++ doesn't work that way. You can't just assign a subclass object to a base class object and expect that to work; this mistake is known as "object slicing".
Also, your if-statement's condition is not comparison, it's assignment.
You have overloaded operator= for the following cases: (pseudocode)
Parent = Parent&&
Child1 = Child1&&
Child2 = Child2&&
However your code then attempts to do Parent = Child1, which wasn't one of those options. Note that the left-hand-side is the class type in which the function is defined - the return value type does not affect function overloading.
There is never implicit conversion from base class to derived class in C++, as that would be too dangerous. (You must use a cast to request that behaviour). For example, in this case it would be wrong to pass a Parent as argument to a function expecting a Child1 because that Parent is not a Child1.
However, there is implicit conversion from derived class to base class reference. So Parent = Child1 will match Parent = Parent&&. It cannot match any of the others because the left-hand-side is not implicitly converted to a derived class.
To solve this problem, your choices include:
Explicitly define Parent = Child1&& and Parent = Child2&& inside Parent (this will need forward declarations)
Have Parent = Parent&& use tag-dispatching or dynamic_cast or otherwise, to achieve the desired behaviour for all of the child classes
As mentioned by others, perhaps your design needs a re-think, as you are slicing on purpose here, but it is rare that slicing is an intended part of an object-oriented design. Possibly you intended Parent p; to actually be a reference or pointer to Parent, instead of an actual Parent.

Unable to access function of derived class in c++

I am trying to access a method of derived class from the object of my base class. I have a base class CBase which is an abstract class,
class CBase{
protected:
char path[255];
public:
virtual void StartBackup()=0;
void setpath(char * path)
{
strcpy(this->path,path);
}
virtual void afunc()
{
printf("Base\n");
}
};
Now two classes Ctype1 and Ctype2 are derived classes from CBase
class CType1:public CBase{
public:
void StartBackup()
{
printf("Type1:%s",path);
}
void afunc()
{
printf("CType1:afunc\n");
}
void myfunc()
{
printf("myfunc\n");
}
};
class CType2:public CBase{
public:
void StartBackup()
{
printf("Type2:%s",path);
}
void afunc()
{
printf("type2:afunc\n");
}
void typefunc()
{
printf("typefunc\n");
}
};
I have a class CManager which has an object of class CBase as its member,
class CManager{
private:
CBase * obj;
public:
CManager(){
obj = NULL;
}
~CManager(){
if(obj)
delete obj;
obj = NULL;
}
void inittype(int type)
{
if(type == 1)
{
obj = new CType1();
obj->myfunc();
}
else
{
obj = new CType2();
obj->typefunc();
}
}
};
In void inittype(int type) function i take the input as type and initialize the CBase object accordingly.
The problem that i am facing is that after creation of object when i try to access myfunc or typefunc i get compilation errors. How can i access these functions(I Dont want to create these functions in the base class)?
EDIT :
The errors that i get are,
'myfunc' : is not a member of 'CBase'
'typefunc' : is not a member of 'CBase'
Thanks
If you only need to access the classes non-derived functions at creation time, then this will work
void inittype(int type)
{
if(type == 1)
{
CType1* temp = new CType1();
temp->myfunc();
obj = temp;
}
else
{
CType2* temp = new CType2();
temp ->typefunc();
obj = temp;
}
}
If you need to access these member functions at other times, you'll need to use a cast - e.g.
CType2* child = dynamic_cast<CType2*>(obj);
Create an inittype virtual function in your base class (doing nothing), then override it in the derived classes as you need.
void CType1::inittype() {
myfunc();
}
void CType2::inittype() {
typefunc();
}
void CManager::inittype(int type)
{
if(type == 1)
{
obj = new CType1();
}
else
{
obj = new CType2();
}
obj->inittype();
}
I'm not clear what you mean by "I Dont want to create these functions in the base class".
You appear to know about pure virtual functions. If you declared the problem functions as pure functions in CBase, you should be able to call them through a CBase * pointer.
One possible confusion in object-oriented languages is that "what type is this" has two answers depending on context. When you create a new object, the type is the exact type. When you access an existing object via a reference or pointer, the type is a set of possible types - the base class and all subclasses the might exist. More precisely, the type of the pointer/reference defines the interface you can use to access the object. That interface must be known without reference to the derived classes (which may not exist when the base class is compiled) so it must be declared in the base class - the virtual methods.
If you want to call something that's only known in the derived class, there are two options. One is to not forget the derived class in the first place. For example...
CType1 *temp = new CType1();
obj = temp;
temp->myfunc();
The other is to determine which derived class you're using at run-time, and use a cast to convert the pointer. The (relatively) safe way to do this is with dynamic_cast.
CType1 *temp = dynamic_cast<CType1> (obj);
if (temp) { temp->myfunc (); }
I haven't covered how you identify the type at run-time. There's "Run-Time Type Identification" (RTTI) built into C++ to do this, but I've very rarely used it. In the rare cases where dynamic_cast is the right thing, I've always known the type for some other reason - either the objects were in a closed set of classes that could be identified via functionality in some interface anyway, or there was only one possibility that could occur in the code that needed the dynamic_cast.
The key words here are "closed set of classes" - if someone else inherits from your classes, you can have unexpected problems when objects of a type you don't know about and therefore cannot identify are accessed by your code. That isn't really a problem with OOP, it's a designed-in feature - you're supposed to be able to extend existing classes in OOP without notifying whoever wrote the base classes, that's what inheritance is for. Though in languages where you can mark a class final, that's probably a good idea if you don't want to allow it in this case (and IIRC C++11 provides a way to do that, I just don't know how to spell it).

How to access child class's datamember when both base and child class have same object name but different types. in C++

struct BaseType
{
int x1;
float x2;
};
struct ChildType
{
int y1;
float y2;
};
Class Base
{
BaseType obj;
void funcBase(BaseType **ptr)
{
*ptr = &obj; // When this assignment happens ofcourse obj is of the BaseType as the LHS ptr is pointing to a BaseType
Now I want to write a C++ equivalent code of the following 2 algorithmic statements,
BaseType's obj.x1 = ChildTypes's obj.y1;
BaseType's obj.x2 = ChildTypes's.obj.y1;
}
};
class Child :: public Base
{
ChildType obj;
};
I wnat to access child's obj.y1 from base and assign it to base's obj.x1.
But 1 thing to remember that object name in base and child is same
"obj".
Can anyone kindly help me in this. Thanks.
Your question is somewhat vague, but from what I can gather, you want something like this:
ChildType* child = dynamic_cast<ChildType*>( &obj );
Now child is pointing to obj, as if it were of type ChildType, assuming the cast is successful.
Read more about typecasting here.
EDIT: I should just mention that typecasting like this should be avoided if a better design can substitute it. Perhaps you should reconsider your overall design for a moment here.
EDIT2: Given your recent edit, here's a more specific block of example code:
ChildType* child = dynamic_cast<ChildType*>( &obj );
obj.x1 = child->y1;
obj.x2 = child->y2;
I think you have an object of type Child that does not implement funcBase() and that you want to call funcBase() on this object and have funcBase() access Child::obj and not Base::obj. If that's the case then I believe you can define Child as
class Child : virtual public Base
{
ChildType obj;
...
}
Virtual inheritance is usually used to resolve the diamond problem but I think you can use it to solve this problem as well.
If my assumption is incorrect then feel free to ignore me.

Fail to return a derived class pointer when overriding a virtual method

This question is about overriding a virtual method in a derived class with a different return type.
For the following code:
class father {
public:
virtual father* ref() { return this; }
};
class child : public father {
virtual child* ref() { return this; }
};
When I try to get a pointer directly, g++ (F15, g++4.5) reports "invalid conversion from father to child"
child m_child;
father* pf = &m_child;
child* pc = pf->ref();
I understand the ref() method in the child class is used and this is probably just a compile time type mismatch.
However, is there any way to do it without explicitly use a type cast?
Extra description:
I understand the reason why compiler report this error. What I need is something out of the box which can access the data in derived object without explicitly convert a pointer.
The father class is used to put different derived child objects into lists or vectors, so when an item is fetch from the list or vector, there is no way to tell which child class it is belong to.
I have internal method to record and check the child class type. But I dont want to explicitly convert the pointer.
For example, I would like to do something like this:
// assuming pf is pointer pointed to an item fetch from a vector
switch(fp->get_type()) {
case child_type1: fp->ref()->list1.push(data); break;
case child_type2: fp->ref()->list2.push(data); break;
case child_type3: fp->ref()->list3.push(data); break;
}
Right now, I need to explicitly declare a new variable or explicitly convert fp to the proper type in each case and each time I need to access a data in derived classes, which are tedious and confusing.
What I expect are: may be some boost libraries can do similar things in another way which I dont know yet, or may be the c++11 standard allows it but a special compiling parameter needs to be set?
Simple answer is "no".
You've lost the extra information (child* rather than father*) about ref when you threw away m_childs type information, by storing it as pointer to base (pf).
One reason why it will never be possible without a cast is this example:
class father {
public:
virtual father* ref() { return this; }
};
class childA : public father {
virtual childA* ref() { return this; }
};
class childB : public father {
virtual childB* ref() { return this; }
};
void should_never_compile(int i)
{
childA a;
childB b;
father pf;
if( i ) { pf=&a; }
else { pf=&b; }
// This is evil and will not compile
childA * pa = pf->ref();
//But this is OK:
childA * pa = dynamic_cast<childA*>(pf->ref() );
}
If you really want to make this doable without the dynamic cast you can just hide the dynamic cast (but it scares me a little)
class father {
public:
virtual father* ref() { return this; }
template<typename T> T* as() { return dynamic_cast<T*>(ref()); }
};
child m_child;
father* pf = &m_child;
child* pc = pf->as<child>();
Your function does what you expect and what you tell it to. The line
child* pc = pf->ref();
is the problem. You call the function "ref()" on a pointer-to-father, which returns (by type) a father *. You assign this - without conversions - to a child *. The implementation of that function returns a child *, but from where you call it that information is not known as you only know that it's a father *. The return type is therefore a father * (as indicated in the class father), and you assign that without conversion to a child *. You can do:
child *pc = m_child.ref();
father *pf = m_child.ref();
father *pf2 = pf->ref();
The problem is that in the call pf->ref(), the type of ref is: father* (father::*)().
That is, ref is resolved statically to be a virtual method with a given signature. And this signature indicates that it returns a father*.
Thus:
int main() {
father f;
father* pf = &f;
child c;
child* pc = &c;
child* xf = pf->ref(); // compile-time failure
child* xc = pc->ref(); // okay
}
The problem is that, in general, starting from a father* you cannot know whether or not you will get a child*, it depends on the dynamic type of the instance. So the compiler assumes the worst case: it must at least be father.

How to avoid C++ cast for specific class methods? Design Pattern?

Suppose I have something like this:
class Father {
public:
virtual int genericMethod (void) =0;
};
class Son1: public Father {
public:
int genericMethod ()
{ }
};
class Son2: public Father {
public:
int genericMethod ()
{ }
int specifClassMethod()
{ }
};
In the main I do the following:
Father * test = new Son2();
test->specifClassMethod(); //Can't do this! It is specific of Class Son2 and is not a virtual method in class Father!
The main question here is to know the better way to access Son2 specific method through Father interface. I want to know if there is a Design Pattern to solve this or another way. I don't wanna to do casts and I don't wanna to put lots of 'if' in my code.
Regards,
Eduardo
Maybe the Visitor-Pattern is the pattern you're looking for.
How Visitor Pattern avoid downcasting
Possible approach is to have specific interface with optional methods, and virtual method to get this interface in the base class (which may return zero):
class SpecificInterface {
public:
virtual ~SpecificInterface()
{ }
virtual int specifClassCmethod() = 0;
{ }
};
class Father {
public:
virtual int genericMethod (void) = 0;
virtual SpecificInterface* getSpecificInterface (void) =0;
};
class Son1: public Father {
public:
int genericMethod ()
{ }
SpecificInterface* getSpecificInterface (void)
{ return 0; }
};
class Son2: public Father, public SpecificInterface {
public:
int genericMethod ()
{ }
int specifClassCmethod()
{ }
SpecificInterface* getSpecificInterface (void)
{ return this; }
};
Usage is following:
Father * test = new Son1();
SpecificInterface * specificAPI = test->getSpecificInterface();
if( specificAPI )
specificAPI->specifClassCmethod();
You couldn't legally solve this with a cast, either, because "test" is pointing to a Father object, not a Son2 object. Casting object types means "Trust me, compiler, this variable actually holds X". It doesn't somehow magically convert a base object into a derived object; it only tells the compiler something you already know that it does not.
If you want behavior that differs by derived class, then move the behavior into a virtual method -- i.e., the code that wants to call specificCLassMethod() belongs in a virtual method of Father.
No. To call methods which only exist in a child class, you'll have to cast to the ch ild class.
While you could create a map which maps function names to functions, add your functions to it from the child class' constructor and then use something like test->callMethod("name"); you'd have to make all those methods have the same signature or use varargs to pass arguments which is not very nice.
You can static_cast<Son2*>(test)->specifClassCmethod(); but that only works if Father * test = new Son2();
If you really have something specific to Son2 then dynamic_cast<> is what you should use. If it is something that could be added as a virtual function to the base class with a default empty behaviour, then you can solve your issue without a cast (but that is not what you wanted to do as you stated in the question)
One design pattern to solve your issue is to use a proxy object. That object would have all the methods susceptible to be called and delegate them to the real object or not.
Advantages of the proxy pattern:
you concentrate the logic needed to differentiate the objects behind to one place
you can add some logging easily
the client code remains simple and the Son classes clean from extra stuff
First of all,you can not create an instance for the class "Father" because it is an abstract class(which has virtual int genericMethod (void) =0; -pure virtual function).Instead an instance can be assigned to it....
Like
Son1* obj_son = new Son1();
Father* obj = obj_son;
//now if you call generic method - son1 method will be called(Father method is over ridden)
obj->genericMethod();
//similarly for son2 class
Son2* obj_son2 = new Son2();
Father* obj2 = obj_son2;
obj2->genericMethod();
obj2->specifClassCmethod();