在构造基类期间访问继承的方法? 我有一个奇怪的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如果您是指使用策略模式,这是通常的解决方案。