在构造基类期间访问继承的方法? 我有一个奇怪的C++问题,我不确定它是否正确地使用这种方法,或者如果我错过了什么。
有一个类在构造基类期间访问继承的方法? 我有一个奇怪的C++问题,我不确定它是否正确地使用这种方法,或者如果我错过了什么。,c++,oop,C++,Oop,有一个类a,它继承自ABaseABase和A都有一个方法Generate(),而A::Generate()应该覆盖ABase::Generate() Generate()从ABase的构造函数中调用 现在我的问题是: 我做了一个新的a(),它首先跳入a的构造函数,然后从那里跳入ABase的构造函数ABase::ABase()现在调用Generate()。我想做的是:A::Generate()应该被执行(因为这会覆盖ABase::Generate()) 不幸的是,它似乎超出了ABase的构造函数,
a
,它继承自ABase
ABase
和A
都有一个方法Generate()
,而A::Generate()
应该覆盖ABase::Generate()
Generate()从ABase的构造函数中调用
现在我的问题是:
我做了一个新的a()
,它首先跳入a的构造函数,然后从那里跳入ABase的构造函数ABase::ABase()
现在调用Generate()
。我想做的是:A::Generate()
应该被执行(因为这会覆盖ABase::Generate()
)
不幸的是,它似乎超出了ABase
的构造函数,只调用了ABase::Generate()
,而从未调用过A::Generate()
这是因为A在这个阶段没有完全构造好吗?或者有没有办法让ABase::ABase()
使用a::Generate()
?您不希望执行a::Generate()
,因为
这将涉及对一个未被调用的类执行函数
构建。C++是有意设计的,以便在
构造时,对象的动态类型是正在创建的类型
构造,正是为了避免此类问题。您不希望执行A::Generate()
,因为
这将涉及对一个未被调用的类执行函数
构建。C++是有意设计的,以便在
构造时,对象的动态类型是正在创建的类型
构造,正是为了避免这类问题。这不容易解决,而且肯定不美观,但您可以这样做:
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
}
};
这不容易解决,而且肯定不漂亮,但你可以这样做:
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
}
};
为了很好地构造和初始化对象,我将把这两个任务彼此分开:
class ABase
{
public:
virtual void Generate()
{
//...
}
};
class A: public ABase
{
public:
virtual void Generate()
{
//...
}
};
现在您必须显式地执行这两个任务
A *someA = new A();
someA->Generate();
…但您可以将其分组,例如
Create()
方法或重新定义新的运算符等。为了更好地构造和初始化对象,我将这两个任务彼此分开:
class ABase
{
public:
virtual void Generate()
{
//...
}
};
class A: public ABase
{
public:
virtual void Generate()
{
//...
}
};
现在您必须显式地执行这两个任务
A *someA = new A();
someA->Generate();
…但您可以将其分组,例如Create()
方法或重新定义new
运算符等。您可以不描述代码,而是发布它吗?没有简单的解决方法:不应从构造函数或析构函数调用虚拟方法。@JoachimPileborg当然您可以调用虚拟函数,它的工作原理与其他任何地方的工作原理完全相同。调用的函数取决于对象的动态类型。在构造过程中,它是当前运行的构造函数的类型。@andre如果您是指使用策略模式,这是通常的解决方案。与其描述代码,你能改为发布它吗?没有简单的解决方法:不应从构造函数或析构函数调用虚拟方法。@JoachimPileborg当然你可以调用虚拟函数,它的工作原理与其他任何地方的工作原理完全相同。调用的函数取决于对象的动态类型。在构造过程中,它是当前正在运行的构造函数的类型。@andre如果您是指使用策略模式,这是通常的解决方案。