我有一个奇怪的C ++问题,我不确定它是否以这种方式正常工作或者我错过了什么。
有一个继承自A
的班级ABase
。 ABase
和A
都有方法Generate()
,而A::Generate()
应该覆盖ABase::Generate()
。
从ABase的构造函数中调用Generate()。
现在我的问题:
我做了new A()
,它首先跳转到A的构造函数,然后从那里进入ABase的构造函数。 ABase::ABase()
现在调用Generate()
。我想做什么:A::Generate()
应该被执行(因为这会覆盖ABase::Generate()
)。
不幸的是,ABase
的构造函数似乎只调用了ABase::Generate()
,而且从不调用A::Generate()
。
我猜是因为A在这个阶段没有完全构建?或者有没有办法让ABase::ABase()
使用A::Generate()
?
答案 0 :(得分:5)
由于这个原因,你不希望A::Generate()
被执行
将涉及在尚未执行的类上执行函数
建造。 C ++是故意设计的,以便在此期间
构造,对象的动态类型是类型
构造,正是为了避免这种问题。
答案 1 :(得分:0)
要解决这个问题并不容易,而且绝对不是很漂亮,但你可能会做到这样的事情:
class ABase
{
public:
ABase()
{
// Normal constructor, calls `Generate`
}
virtual void Generate() { ... }
// ...
protected:
struct do_not_call_generate_tag {};
const static do_not_call_generate_tag do_not_call_generate;
ABase(const do_not_call_generate_tag)
{
// Same as the normal `ABase` constructor, but does _not_ call `Generate`
}
};
class A : public ABase
{
public:
A()
: ABase(ABase::do_not_call_generate)
{
// Other initialization
PrivateGenerate();
}
void Generate()
{
PrivateGenerate();
}
private:
void PrivateGenerate()
{
// Do what your old `Generate` does
}
};
答案 2 :(得分:0)
为了拥有构造良好的和初始化对象,我将这两个任务彼此分开:
class ABase
{
public:
virtual void Generate()
{
//...
}
};
class A: public ABase
{
public:
virtual void Generate()
{
//...
}
};
现在你必须明确地执行这两项任务
A *someA = new A();
someA->Generate();
...但你可以在Create()
方法或重新定义new
运算符等。