Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to declare object as base class but use derived class method?

Consider a Base class and a derived class that inherits from it called Child.
Assume the Base class has a member function declared virtual, and that Child overrides that function.
I would like to declare a variable as a Base class object, initialize it using the Child derived class constructor, and then use the Child class version of the member function.
In other words, the following C++ program:

#include <iostream>

class Base {
public:
    virtual int give_number(int x) { return x; }
};

class Child : public Base {
public:
    int give_number(int x) { return x+1; }
};

int main() {
    Base base;
    Child child;
    Base child2;
    child2 = Child();
    std::cout << "Base says " << base.give_number(1) << "\n";
    std::cout << "Child says " << child.give_number(1) << "\n";
    std::cout << "Child2 says " << child2.give_number(1) << "\n";
}

results in the following output:

Base says 1
Child says 2
Child2 says 1

But I would instead prefer the following output:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Base says 1
Child says 2
Child2 says 2

Is there a way to accomplish this?

>Solution :

In the statement:

child2 = Child();

You are slicing the Child object, which is why the Child::give_number() method is not being called. child2 is a Base instance, never a Child instance. During the assignment, only the Base portion of the new Child object is copied into child2.

You must use a pointer or reference when calling a virtual method polymorphically, eg:

#include <iostream>

class Base {
public:
    virtual ~Base() = default;
    virtual int give_number(int x) { return x; }
};

class Child : public Base {
public:
    int give_number(int x) override { return x+1; }
};

int main() {
    Base base;
    Child child;
    Child child2;
    Base& base2 = child2;
    std::cout << "Base says " << base.give_number(1) << "\n";
    std::cout << "Child says " << child.give_number(1) << "\n";
    std::cout << "Base2 says " << base2.give_number(1) << "\n";
}

Or:

#include <iostream>

class Base {
public:
    virtual ~Base() = default;
    virtual int give_number(int x) { return x; }
};

class Child : public Base {
public:
    int give_number(int x) override { return x+1; }
};

int main() {
    Base base;
    Child child;
    Child child2;
    Base* base2 = &child2;
    std::cout << "Base says " << base.give_number(1) << "\n";
    std::cout << "Child says " << child.give_number(1) << "\n";
    std::cout << "Base2 says " << base2->give_number(1) << "\n";
}

Or:

#include <iostream>
#include <memory>

class Base {
public:
    virtual ~Base() = default;
    virtual int give_number(int x) { return x; }
};

class Child : public Base {
public:
    int give_number(int x) override { return x+1; }
};

int main() {
    Base base;
    Child child;
    //Base* child2 = new Child;
    std::unique_ptr<Base> child2 = std::make_unique<Child>();
    std::cout << "Base says " << base.give_number(1) << "\n";
    std::cout << "Child says " << child.give_number(1) << "\n";
    std::cout << "Child2 says " << child2->give_number(1) << "\n";
    //delete child2;
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading