在下面的玩具示例中,我有一个基类和一个从其继承的类。子类将覆盖方法doSomething()
。但是,当我将子类的实例传递给需要基类的函数时,我得到了基类的行为,即输出为I'm the base class!
而不是I'm the child class!
。我如何防止这种情况发生以及为什么发生(我猜正在发生某种隐式强制转换?)。
非常感谢!
#include <iostream>
using namespace std;
class BaseClass {
public:
void doSomething() {
cout << "I'm the base class!";
}
};
class SubClass : public BaseClass {
public:
void doSomething() {
cout << "I'm a child class!";
}
};
void thisFunction(BaseClass & instance) {
instance.doSomething();
}
int main(int, char*[]) {
SubClass sc;
thisFunction(sc);
}
答案 0 :(得分:5)
您的BaseClass::doSomething()
不是虚拟的。这样,它就不能被覆盖,而只能被阴影覆盖。尝试将其签名更改为
class BaseClass {
virtual void doSomething() { /* ... */ }
};
SubClass
不需要进行任何更改,但是,使用override
关键字是一种很好的做法(您的示例代码就是一个很好的例子-用{{标记方法1}}如果在任何基类中不是完全相同的函数签名,override
会使编译器抱怨:
virtual
除此之外,请同时将class SubClass : public BaseClass {
void doSomething() override { /* ... */ }
};
析构函数设为虚拟(或BaseClass
),否则当通过protected
删除SubClass
实例时,您可能会面临不确定的行为指针。