如何将对象声明为基类但使用派生类方法?

问题描述 投票: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个回答
0
投票

声明中:

child2 = Child();

您正在切片

Child
对象,这就是为什么
Child
覆盖的方法没有被调用。多态调用虚方法时必须使用指针或引用,例如:

#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;
    Base* child2 = new 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.