派生类型的对象上未调用基类方法:没有指针和引用的多态性[重复]

问题描述 投票:0回答:1

考虑一个

Base
类和一个从它继承的派生类,称为
Child
。 假设
Base
类有一个声明为
virtual
的成员函数,并且
Child
覆盖该函数。 我想将变量声明为
Base
类对象,使用
Child
派生类构造函数初始化它,然后使用
Child
类版本的成员函数。 换句话说,以下 C++ 程序:

#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";
}

产生以下输出:

Base says 1
Child says 2
Child2 says 1

但我更喜欢以下输出:

Base says 1
Child says 2
Child2 says 2

有办法做到这一点吗?

c++ polymorphism virtual-functions
1个回答
2
投票

声明中:

child2 = Child();

您正在切片

Child
对象,这就是为什么
Child::give_number()
方法没有被调用。
child2
是一个
Base
实例,而不是
Child
实例。在赋值过程中,仅新
Base
对象的
Child
部分被复制到
child2
中。

多态调用虚方法时必须使用指针或引用,例如:

#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";
}

或者:

#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";
}

或者:

#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;
}
© www.soinside.com 2019 - 2024. All rights reserved.