#include<stdio.h>
class parent
{
public:
parent()
{
}
};
class child : public parent
{
public:
child()
{
}
};
class master
{
public:
void view(parent a)
{
printf("view parent instances");
}
void view(child b)
{
printf("view child instances");
}
};
int main()
{
parent *ptr;
master mymaster;
ptr = new child;
mymaster.view(*ptr);
return 0;
}
output : "view parent instances"
I create a pointer from parent class. then I declared that pointer as child type. when i run mymaster.view(*ptr); , this always go to first view function (void view(parent a)), how to make it go to (void view(child b)). thankyou
With a little refactoring and a slightly different approach, you could use virtual functions. This enables the function from derived classes to be used when called using a pointer like below.
#include<stdio.h>
class parent
{
public:
parent()
{
}
virtual void view()
{
printf("View parent");
}
};
class child : public parent
{
public:
child()
{
}
virtual void view()
{
printf("View child");
}
};
class master
{
public:
void view(parent *a)
{
a->view();
}
};
int main()
{
parent *ptr;
master mymaster;
ptr = new child;
mymaster.view(ptr);
return 0;
}
This will output "View child". The same code without the virtual keywords will output "View parent". Note that the keyword only needs to be in the parent class, but is often used in the derived classes too for clarity.
The Wikipedia article on virtual functions explains the situation pretty well:
Virtual functions are resolved 'late'. If the function in question is
'virtual' in the base class, the most-derived class's implementation
of the function is called according to the actual type of the object
referred to, regardless of the declared type of the pointer or
reference. If it is not 'virtual', the method is resolved 'early' and
the function called is selected according to the declared type of the
pointer or reference.
Since the actual type of the object here is a child, the virtual function makes sure that the child's functionality is called even though the pointer is of parent type.
The type of *(parent*) is parent, so the method that gets called is view(parent). If you want to invoke view(child), you need to cast the pointer to a child* before passing it in, however...
You're using OOP backwards. You don't define multiple methods that know how to consume each specific type of sub-class, you define one method that can respect the contract provided by the parent class, and the sub-classes do their own thing internally.
ptr is a pointer to a parent object.
If you want to have the view(child) function called, you need to pass a child object to the function call.
Alternatively, you can cast it to a child pointer
mymaster.view(*(child*)ptr);
but you're likely to end up with all kinds of other problems.
The compiler decides the matching method according to the best choice.
The compiler sees that the variable is of type parent, so it calls the matching method.
Related
So i have the following code:
#include <iostream>
using namespace std;
class Parent
{
int x;
public:
Parent(){x=10;}
void f(){cout<<x;}
};
class Child: public Parent
{
int x;
public:
Child(){x=20;}
void f(){cout<<x;}
};
int main()
{
Parent *pp;
Child c;
pp=&c;
pp->f();
return 0;
}
As you can see, i have two classes, Parent class and Child class publicly inherited from Parent class, so i wanted to see what can i do with pointer to a parent class.
I thought that it would be possible to use pointer to the parent class and use it on a child object, as i did in main, however, whenever i run this code, it prints out 10, which is the value i have for parent class variable x, considering that i made pp to point to child object, shouldn't it call the function f() defined in the child class and therefore, it should print the value of 20. What am i missing here? Any help appreciated!
The method f has to be virtual. As a start read this reference maybe helps.
#include <iostream>
using namespace std;
class Parent
{
int x;
public:
Parent(){x=10;}
virtual void f(){cout<<x;}
// ^^^^^^^ see this
};
class Child: public Parent
{
int x;
public:
Child(){x=20;}
virtual void f(){cout<<x;}
// ^^^^^^^ and this
// or since C++11 with override:
// void f() override {cout<<x;}
};
int main()
{
Parent *pp;
Child c;
pp=&c;
pp->f();
return 0;
}
Demo
There are at least two problems in the code.
First, the function f() must be declared virtual at least in the Parent class (with C++11 and later it is then good practice to append the keyword override in the Child class). The function being virtual is the mechanism that makes it possible to call the Child implementation via a Parent pointer.
Second, the variable x is declared both in the Parent and the Child class. This means that the Child object has two variables called x and by default x in Child functions will refer to the x declared in the Child class (the copy in the Parent class must be public or protected to be accessible from Child and must then, because of the name overlap, be referred to via a Parent type pointer or by explicitly specifying the class as in Parent::x).
I want to edit an inherited function name(), and ensure that the inherited function info() will call child::name() rather than parent::name() when called by an instance of child.
class parent {
public:
string name() { return "parent"; }
void info() {
cout << "This class is " << name() << endl;
}
};
class child : public parent {
public:
string name() { return "child"; }
};
int main() {
parent p;
child c;
p.info(); // outputs "parent"
c.info(); // outputs "parent" - I want "child"
}
How can I get c.info() to use child::name()? I will never need name() outside of info(), and I don't really want to duplicate info() in the child class, as I am trying to avoid repeating a rather long block of code in my real problem.
You have declared a non polymorphic function
If a member function f() of your parent is not virtual, it is not polymorphic. So if this function is called by another function of the parent, it is parent::f() that will be called.
If this function is hidden by another function f() in the child, with exactly the same signature, and if this function is called by another function of the child, it is child::f() that will be called.
Interestingly, if you invoke the function directly for an object, the function of the declared type of the object will be invoked.
Polymorphic functions
If you want to make your function polymorphic, you have to define it as virtual in the parent. Suppose it is overriden in the child. In this case, when you call f(), it will always be the f() defined for the real type of the object.
class parent {
public:
virtual string name() { return "parent"; }
...
}
};
class child : public parent {
public:
string name() override { return "child"; }
};
With this programm, you'll get this result:
This class is parent
This class is child
So, I know something like this is asked a lot, but the other answers seem to indicate that this should work, so I thought I'd ask about my code specifically. I spend more time in .NET and Java, so maybe I'm forgetting something.
I'm creating a base widget and a set of specific widgets (buttons, other graphical items). I'm trying to loop through a linked list of widgets and what I would like is for the specific rendering method for that specific widget to be called. Below is simplified code that demonstrates my problem, on my first call to Render, the specific render function is called. If I pass a cGeneralWidget pointer to a function which calls the Render object, the base method was called. I thought, as long as I send a pointer, C++ is smart enough to know what the object really is and call the overridden method.
Otherwise, whats the correct way to deal with a collection of base objects and call the derived methods as appropriate?
Thank you.
class cGeneralWidget
{
public:
void Render()
{
int a = 99;
}
};
class cSpecificWidget : public cGeneralWidget
{
public:
void Render()
{
int a = 99;
}
};
void GeneralRenderingFunction(cGeneralWidget * b)
{
b->Render(); // <-- calls the base function
}
int main(int argc, char* argv[])
{
cSpecificWidget wd;
wd.Render(); // <-- calls the derived function
GeneralRenderingFunction(&wd);
return 0;
}
You should define Render() method in your base class with virtual keyword and in your derived class with override keyword. If you don't put virtual keyword in your base class implementation then C++ wouldn't mark it as virtual.
class cGeneralWidget
{
public:
virtual void Render()
{
int a = 99;
}
};
class cSpecificWidget : public cGeneralWidget
{
public:
void Render() override
{
int a = 99;
}
};
in your base class
class cGeneralWidget
{
public:
virtual void Render()
{
int a = 99;
}
};
Render has to be virtual so it overrides it
Note : A virtual function a member function which is declared within base class and is re-defined (Overriden) by derived class. When you refer to a derived class object using a pointer or a reference to the base class, you can call a virtual function for that object and execute the derived class’s version of the function.
I'm working with some production code, some of which I cannot safely modify (without breaking things). My issue is that it I would like to use a specific method, one of the parameters of which is a pointer to a class. However the class as the parameter does not do what I want it to.
So I wrote a sub-class of that class and am attempting to call the above function, but it still uses the parent class' methods.
I have a MWE below:
#include <iostream>
class Parent
{
public:
Parent() {};
void method() {std::cout<<"in Parent\n";}
};
class Child : public Parent
{
public:
Child() {};
void method() {std::cout<<"in Child\n";}
};
void secondMethod(Parent* Pptr)
{
Pptr->method();
}
int main()
{
Child c = Child();
Parent* parentPtr = &c;
c.method();
parentPtr->method();
secondMethod(parentPtr);
secondMethod(&c);
return 0;
}
In the above example running this the output is of course:
in Child
in Parent
in Parent
in Parent
I believe the issue is slicing? Basically I'm casting to the pointer of the parent class, so it is considered as a Parent.
I have seen some ways around this by making methods virtual in the parent class but I don't have that option.
Is there some way to make secondMethod actual use the child's method? Specifically without changing the Parent class OR the secondMethod.
No not really if you aren't able to change the parent class or 'secondMethod'. The constructor of 'secondMethod' defines its parameter as Parent*. Passing a Child* to 'secondMethod' will cause the Child* to be upcast to Parent* and in turn will cause Parent's implementation of 'method' to be called.
If you can not change method to virtual function, you may can import template to solve your problem.
template<typename T>
void secondMethod(T* Pptr)
{
Pptr->method();
}
it may can work!!!
I am studying inheritance and polymorphism in C++ and I came across this example:
class Parent
{
public:
void a()
{
std::cout << "parentA";
}
virtual void b()
{
std::cout<<"parentB";
}
};
class Child : public Parent
{
public:
void b()
{
std::cout<<"childB";
}
};
Then in main:
int main()
{
Parent i= Child();
i.b(); //why doesn't this give parentB?
Parent *j= new Child();
j->b();
}
The outputs are parentA and childB respectively but I can't understand why. (isn't b() overriding?)
The first case should give parentB, since the object i has type Parent, not Child. The Child object is sliced - that is, its Parent subobject is copied to create i of type Parent, then the temporary Child is destroyed. You can often prevent confusing behaviour like this by making base classes abstract (that is, giving them pure virtual functions), so that they can't be instantiated.
The second case should give childB, since the object that j points to has dynamic type Child.
You have "sliced" the Child class into the Parent class. In order to access virtual methods, you need to store the instance polymorphically, like you have with your second example. Polymorphic variables are pointers and references.