我有三个类:Base,Derived(继承自Base)和Stats(使用Base)。
程序生成一个Derived对象,在程序执行期间可以删除和重建几次。它还设置一个Stats对象,该对象只会被创建一次,但需要在Derived对象的Base上调用函数。因为可以重建Derived对象,所以Stats对象将需要对Base的指针的引用,因为指针的值可能会改变。但是,当我在main中构造一个新的Derived时,Stats类中的引用不会看到新对象。
在下面的示例中,d和m_obj都为null,然后当我创建一个新的Derived实例时,m_obj仍为null。这对我来说没有意义。令人困惑的是,如果我将行Derived* d = 0;
更改为Base* d = 0;
,它就可以正常工作。有什么想法吗?
#include <iostream>
using namespace std;
class Base {
};
class Derived : public Base {
};
typedef Base* const base_ptr;
class Stats {
public:
Stats(Base * const &obj) : m_obj(obj) {
cout << "In Stats():" << endl;
cout << " m_obj = " << m_obj << endl;
}
void f() const {
cout << "In f:" << endl;
cout << " m_obj = " << m_obj << endl;
}
private:
base_ptr &m_obj;
};
int main() {
Derived* d = 0;
cout << "d = " << d << endl;
Stats s(d);
d = new Derived();
cout << "d (after new) = " << d << endl;
s.f();
return 0;
}
答案 0 :(得分:3)
您的Stats
实际上是d
值的临时副本。这是因为d
不属于Base * const &
类型(但可以转换为)。
答案 1 :(得分:3)
您正在创建对临时Base *
的引用,该引用指向d
指向的内容(在本例中为NULL)。在调用构造函数的行完成执行后,该临时文件被销毁。恭喜,您刚刚调用了未定义的行为!在那之后,任何事情都可能发生。
基本上,如果你扩展出真正发生的事情,这一行就是这样的:
Stats s(d);
确实
{
Base * const tmp = d;
Stats s(tmp);
}
当然,s
不会像在这个例子中那样消失。
当d
的类型为Base *
时,编译器不必进行任何类型转换,因此不必创建任何临时值。