以下是我的代码的摘要:
基类:
#include <iostream>
using namespace std;
class Base {
public:
Base() { cout << "Base constructor" << endl; }
~Base() { cout << "Base destructor" << endl; }
virtual void func(void) const { cout << "base" << endl; }
};
派生类:
#include "Base.h"
class Derived : public Base {
public:
Derived() { cout << "Derived constructor" << endl; }
~Derived() { cout << "Derived destructor" << endl; }
void func(void) const { cout << "derived" << endl; }
};
测试类:
#include "Derived.h"
class Test {
public:
const Base& base;
Test(const Base& _base) : base(_base) { cout << "Test constructor" << endl; }
void test() { base->func(); }
~Test() { cout << "Test destructor" << endl; }
};
测试的主要功能:
#include "Test.h"
int main(void) {
Test* t = new Test(Derived());
t->test();
return 0;
}
当我运行main函数时,正在调用 func 的 Base 版本。
但是,如果我将主要功能更改为以下内容:
#include "Test.h"
int main(void) {
Derived d;
Test* t = new Test(d);
t->test();
return 0;
}
正确调用 func 的派生版本。 我还试图改变 const Base&amp; 测试到 Base * base 的基础。然后使用
构建测试Test* t = new Test(new Derivec())
事实证明 func 的派生版本也被正确调用。
我在想,如果我使用引用或指针,那么多态就会起作用。
有人可以向我解释为什么第一个版本没有正确调用派生类方法吗?
非常感谢你的帮助!
答案 0 :(得分:2)
你有一个悬空参考问题。
Test* t = new Test(Derived());
您正在使用Derived
类型的临时对象来构建t
。在Test
的构造函数返回后,临时对象被删除。
因此,您的程序有不确定的行为。
如果您使用
Derived d;
Test* t = new Test(d);
您获得了预期的行为,因为t
没有悬空参考。
另请注意
void test() { base->func(); }
不应该编译,因为base
是一个引用。那条线必须是:
void test() { base.func(); }