考虑一个
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
有办法做到这一点吗?
声明中:
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;
}