I am trying to make a vector of Child and Parent objects. I have a function foo() in Child class which overrides foo() in Parent, and prints No instead of Yes. However, when I call the foo() function of all objects in the vector the parent foo() function is run for the child object. Is there a way to have all children objects in the vector to run the overridden function while parent objects run the parent function?
To extend the question can that also be done for multiple classes which extend the Parent class and override the foo() function.
Here is the code:
#include <iostream>
#include <vector>
#include <memory>
using namespace std;
class Parent {
public:
Parent () {
cout << "New Parent" << endl;
}
void foo() {
cout << "Yes" << endl;
}
};
class Child : public Parent {
public:
Child(): Parent() {
cout << "New Child" << endl;
}
void foo() {
cout << "No" << endl;
}
};
int main()
{
vector<std::unique_ptr<Parent>> v;
v.push_back(std::make_unique<Parent>());
v.push_back(std::make_unique<Child>());
for (auto i = v.begin(); i != v.end(); ++i){
(*i)->foo();
}
return 0;
}
The output is:
New Parent
New Parent
New Child
Yes
Yes
The output i would like is:
New Parent
New Parent
New Child
Yes
No
foo() needs to be declared as virtual in Parent in order for Child (and other descendants) to override it.
Parent should also have a virtual destructor, as well, so that descendant destructors are called correctly when delete is called on a Parent* pointer (such as by std::unique_ptr<Parent>).
Try this:
class Parent {
public:
Parent () {
cout << "New Parent" << endl;
}
virtual ~Parent () {}
virtual void foo() {
cout << "Yes" << endl;
}
};
Related
I would like to identify which child classes initialize pointers in a vector.
I prepare a vector that contains different types of override classes. After that, I set it as an argument in the same function. In the function, I would like to identify which classes initialize this argument and apply different processes for each class.
This is the code and current output.
#include <memory>
#include <iostream>
#include <vector>
class Parent
{
public:
Parent() {};
virtual ~Parent() {};
virtual void print()
{
std::cout << "I am parent!" << std::endl;
}
};
class ChildA : public Parent
{
public:
ChildA() {};
~ChildA() {};
void print() override
{
std::cout << "I am child A!" << std::endl;
}
};
class ChildB : public Parent
{
public:
ChildB() {};
~ChildB() {};
void print() override
{
std::cout << "I am child B!" << std::endl;
}
};
void func(std::unique_ptr<Parent>& pa)
{
pa->print();
//if (pa is initialized from Parent)
//{
//}
//if (pa is initialized from ChildA)
//{
//}
//if (pa is initialized from ChildB)
//{
//}
return;
}
int main(int argc, char** argv)
{
std::unique_ptr<Parent> pa = std::make_unique<Parent>();
std::unique_ptr<ChildA> chA = std::make_unique<ChildA>();
std::unique_ptr<ChildB> chB = std::make_unique<ChildB>();
std::vector<std::unique_ptr<Parent>> mList;
mList.push_back(std::move(pa));
mList.push_back(std::move(chA));
mList.push_back(std::move(chB));
for (auto& l : mList)
func(l);
return 0;
}
output
I am parent!
I am child A!
I am child B!
Could you tell me any idea?
Thank you.
The purpose of doing polymorphic code with virtual functions is usually so you can avoid doing "is this an X" style tests. Instead you create a virtual function doSpecialStuff in the base class and call it via a base class pointer (like print in your code), which then does the appropriate operations for each derived class.
If you really want to test the type, use dynamic_cast:
if(auto child_ptr=dynamic_cast<ChildA*>(pa.get())){
child_ptr->child_A_function();
}
I have the following dummy code:
#include <iostream>
#include <vector>
using namespace std;
class Parent {
public:
void printHello() {
cout << "Hello Parent" << endl;
}
};
class Child : public Parent {
public:
void printHello() {
cout << "Hello Child" << endl;
}
};
int main() {
vector<Parent*> list;
Child child;
list.push_back(&child);
list[0]->printHello();
}
Output: Hello Parent
I am trying to create a list of objects of classes derived from the parent class. Iterating over them and running a method they all inherit and override.
I had assumed the method in the child class would have overridden the method in the parent class.
I have also tried the approach of using vector<Parent> instead of vector<Parent*>.
The result has been the same. How can I call the methods of the derived classes instead of the parent class?
Use virtual methods - http://en.cppreference.com/w/cpp/language/virtual. Read more about them here.
#include <iostream>
#include <vector>
class Parent {
public:
// using virtual keyword
virtual ~Parent() = default;
virtual void printHello() const { std::cout << "Hello Parent" << std::endl; }
};
class Child : public Parent {
public:
// using override keyword though its not necessary
void printHello() const override { std::cout << "Hello Child" << std::endl; }
};
int main()
{
std::vector<Parent *> list;
Child child;
list.push_back(&child);
list[0]->printHello();
}
Output -
Hello Child
In C++ you have to use virtual in the parent class method definition to specify that you are going to use a polymophic method. The default behavior in C++ is not polymorfic.
#include <iostream>
#include <vector>
using namespace std;
class Parent {
public:
virtual void printHello() {
cout << "Hello Parent" << endl;
}
};
class Child : public Parent {
public:
void printHello() {
cout << "Hello Child" << endl;
}
};
Check this out for more info: Polymorphism in C++
To get the behavior you want, that method needs to be declared virtual in the parent class. See http://en.cppreference.com/w/cpp/language/virtual for more information.
I am deriving an object from two parent classes. These two parents each have different types of properties, but I want the child to keep them in sync with each other. However, I want to disallow users of the library from treating Child like a ParentA or a ParentB accidentally via slicing. For example:
#include <iostream>
class ParentA
{
public:
void modify()
{
std::cout << "modifyA" << std::endl;
}
void readA()
{
std::cout << "readA" << std::endl;
}
};
class ParentB
{
public:
void modify()
{
std::cout << "modifyB" << std::endl;
}
void readB()
{
std::cout << "readB" << std::endl;
}
};
class Child : public ParentA, public ParentB
{
public:
void modify()
{
// Do some bounds checking to make sure ParentA and ParentB stay in sync, then:
ParentA::modify();
ParentB::modify();
std::cout << "modifyChild" << std::endl;
}
};
void Change(ParentA object)
{
object.modify();
}
int main()
{
std::cout << "This is standard:" << std::endl;
ParentA parentA;
parentA.modify();
ParentB parentB;
parentB.modify();
Child child;
child.readA();
child.readB();
child.modify();
std::cout << "Want to avoid this:" << std::endl;
Change(child);
return 0;
}
This call to Change(child); calls ParentA's modify() function, in which the ParentA properties can get out of sync with the ParentB properties, leaving the Child in a bad state.
There are many functions (the read*() ones here) in ParentA and ParentB that I don't want to have to manually forward from Child, so I can't derive privately.
Is there a way to make this call to Change(child) produce a compiler error (without changing the signature of Change)?
There is in fact a way to do this (although said you didn't like it): private or protected inheritance is the C++ mechanism to achieve what you want.
Bear in mind that since your child class is trying to keep some sort of invariant between A and B, if you inherit publicly, someone will find a way to use A or B's interface to violate the invariant anyway so you need to protect against those being used in the child directly, which the restricted inheritance does perfectly.
If there are then some methods in the parent that don't affect the two-class invariant you can using those down into the public section of Child.
As the comments already say the cleanest way might be to just inherit from ParentA and ParentB with private and forward the needed functions.
I had another idea: You could extract the functionality of ParentA and ParentB into 2 abstract classes (AbstractParentA,AbstractParentB) and use these classes as base classes.
This would give you the desired behaviour:
#include <iostream>
class AbstractParentA
{
virtual void no_instance() = 0;
public:
void modify()
{
std::cout << "modifyA" << std::endl;
}
void readA()
{
std::cout << "readA" << std::endl;
}
};
class AbstractParentB
{
virtual void no_instance() = 0;
public:
void modify()
{
std::cout << "modifyB" << std::endl;
}
void readB()
{
std::cout << "readB" << std::endl;
}
};
class ParentA : public AbstractParentA
{
virtual void no_instance() override {}
};
class ParentB : public AbstractParentB
{
virtual void no_instance() override {}
};
class Child : public AbstractParentA, public AbstractParentB
{
virtual void no_instance() override {}
public:
void modify()
{
// Do some bounds checking to make sure ParentA and ParentB stay in sync, then:
AbstractParentA::modify();
AbstractParentB::modify();
std::cout << "modifyChild" << std::endl;
}
};
void Change(ParentA object)
{
object.modify();
}
int main()
{
std::cout << "This is standard:" << std::endl;
ParentA parentA;
parentA.modify();
ParentB parentB;
parentB.modify();
Child child;
child.readA();
child.readB();
child.modify();
std::cout << "Want to avoid this:" << std::endl;
Change(child);
return 0;
}
error C2664: 'void Change(ParentA)': cannot convert argument 1 from 'Child'
note: No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
I have the following two classes. Since Child inherits from Father, I think that Child::init() overrides Father::init(). Why, when I run the program, I get "I'm the Father" and not "I'm the Child"? How to execute Child::init()?
You can test it here: https://ideone.com/6jFCRm
#include <iostream>
using namespace std;
class Father {
public:
void start () {
this->init();
};
void init () {
cout << "I'm the father" << endl;
};
};
class Child: public Father {
void init () {
cout << "I'm the child" << endl;
};
};
int main (int argc, char** argv) {
Child child;
child.start();
}
Currently Child::init is hiding Father::init, not overriding it. Your init member function needs to be virtual in order to get dynamic dispatch:
virtual void init () {
cout << "I'm the father" << endl;
};
Optionally, you could mark Child::init as override to be explicit that you want to override a virtual function (requires C++11):
void init () override {
cout << "I'm the child" << endl;
};
You should define the function with function specifier virtual
For example
#include <iostream>
using namespace std;
class Father {
public:
virtual ~Father() {}
void start () {
this->init();
};
virtual void init () const {
cout << "I'm the father" << endl;
};
};
class Child: public Father {
void init () const override {
cout << "I'm the child" << endl;
};
};
int main()
{
Child child;
child.start();
return 0;
}
Otherwise function start searches name init in the scope of its own class. And because function init is not virtual that is it is not overriden in the derived class the base class function init is called.
If you want the child to override the init method, you must make the init method in the base class virtual.
class Father {
public:
void start () {
this->init();
};
virtual void init () {
cout << "I'm the father" << endl;
};
};
A class that re-declares and re-implements a virtual method of one of its bases, is said to override that method. In order for late binding to occur for a method, you need to declare that method virtual.
I'm having trouble on my c++ code ..
class GrandParent {
public:
GrandParent()
{
printMe();
}
virtual void printMe()
{
std::cout << "GrandParent: printme" << std::endl;
}
}
class Parent : public GrandParent {
public:
Parent(){}
virtual void printMe()
{
std::cout << "Parent: printMe!" << std::endl;
}
}
class Child : public Parent {
public:
Child(){}
void printMe()
{
std::cout << "Child: printMe!" << std::endl;
}
}
int main()
{
Child *p = new Child();
delete p;
}
When I run this code, it prints "GrandParent: printMe".
my goal is to print "Child: printMe!". Is there something wrong in overriding printMe?
What you're trying to do isn't possible. At the time of GrandParent's constructor, the only part of the Child object that has been constructed and initialized is the GrandParent part - including the vtable. That is, when you call printMe(), the entry will be GrandParent's. It's only after Child gets constructed that the vtable entry for printMe() gets updated to point to Child::printMe.
Note that it's good that C++ works like this. If Child::printMe had been the one called, then you'd be calling a member function on a not-yet-constructed object. Nothing good can come of that.
Short answer: That's how C++ works.
When a virtual method is called from the constructor, not the method of the runtime class is used. Instead the method of the compile time class is used.
But there might be an escape using the Curiously Recurring Template Pattern as shown here:
#include <iostream>
template <class T>
class Base
{
protected:
Base()
{
T::printMe();
}
};
class GrandParent : Base<GrandParent>
{
public:
GrandParent()
: Base<GrandParent>()
{}
static void printMe()
{
std::cout << "GrandParent: printMe!" << std::endl;
}
};
class Parent : public GrandParent, public Base<Parent>
{
public:
Parent()
{}
static void printMe()
{
std::cout << "Parent: printMe!" << std::endl;
}
};
class Child : public Parent, public Base<Child>
{
public:
Child()
{}
static void printMe()
{
std::cout << "Child: printMe!" << std::endl;
}
};
int main()
{
GrandParent a;
std::cout << "..." << std::endl;
Parent b;
std::cout << "..." << std::endl;
Child c;
std::cout << "..." << std::endl;
}
Output:
GrandParent: printMe!
...
GrandParent: printMe!
Parent: printMe!
...
GrandParent: printMe!
Parent: printMe!
Child: printMe!
...
But yeah, then you have to deal with static methods and multiple inheritence.