【发布时间】:2015-05-01 08:39:20
【问题描述】:
我有以下代码:
class A {
public:
A();
virtual int Compute() = 0;
int inited_val;
};
class B: A {
public:
B(int data): mydata(data) {};
int Compute();
int mydata;
};
A::A() {
inited_val = Compute();
};
int B::Compute() {
return mydata; // long computation...
}
int main() {
B b(42);
return 0;
}
这将不起作用,因为不可能在基类的构造函数中使用B::Compute(它会调用不存在的A::Compute)。
如何确保inited_val 是从派生类中的Compute 函数中填充的?我可以从 B 构造一个对象并在之后填充它,或者使用在构造函数之后直接调用的 init 函数,但这似乎容易出错(我可能会忘记这样做)。
(想象一下Compute 函数的成本很高,并且使用的数据仅在派生类中可用。)
我在http://isocpp.org/wiki/faq/strange-inheritance#calling-virtuals-from-ctor-idiom 上找到了如何解决此问题的建议,并尝试使用create 函数来实现该方法,但我不清楚如何在不明确依赖B 的情况下编写A::create?
A* A::Create() {
A* p = ???;
inited_val = p->Compute();
return p;
}
【问题讨论】:
-
不能把继承改成public,从派生类构造函数初始化inited_val吗?
-
这是可能的,但是从 A 派生的每个人都需要这样做并且不要忘记这一点。 (而且它也会重复代码,因为该行在所有派生构造函数中都是相同的。)
标签: c++ inheritance constructor initialization