在派生构造函数中访问基成员的问题

Posted

技术标签:

【中文标题】在派生构造函数中访问基成员的问题【英文标题】:Problem accessing base member in derived constructor 【发布时间】:2010-06-01 06:08:17 【问题描述】:

给定以下类:

class Foo

    struct BarBC
    
    protected:
        BarBC(uint32_t aKey)
            : mKey(aKey)
              mOtherKey(0)

    public:
        const uint32_t mKey;
        const uint32_t mOtherKey;
    ;


    struct Bar : public BarBC
    
        Bar(uint32_t aKey, uint32_t aOtherKey)
            : BarBC(aKey),
              mOtherKey(aOtherKey) // Compile error here
    ;
;

我在指示的地方遇到编译错误:

error: class `Foo::Bar' does not have any field named `mOtherKey'.

谁能解释一下?我怀疑这是一个语法问题,因为我的 Bar 类是在 Foo 类中定义的,但似乎找不到解决方法。

这是简单的公共继承,所以mOtherKey 应该可以从Bar 构造函数中访问。对吧?

还是与 mOtherKey 是 const 并且我已经在 BarBC 构造函数中将其初始化为 0 的事实有关?

【问题讨论】:

【参考方案1】:

您不能通过成员初始化器列表来初始化基类的成员,只能通过直接和虚拟基类以及类本身的非静态数据成员来初始化。 而是将其他参数传递给基类的构造函数:

struct BarBC 
    BarBC(uint32_t aKey, uint32_t otherKey = 0)
      : mKey(aKey), mOtherKey(otherKey)
    
    // ...
;

struct Bar : public BarBC 
    Bar(uint32_t aKey, uint32_t aOtherKey)
      : BarBC(aKey, aOtherKey)
    
;

【讨论】:

@George - 谢谢。我试图默认初始化基类构造函数中的所有 const 数据成员(以避免编译错误),然后在派生构造函数中设置派生类特定成员(同时仍将成员留在基类中)。无论如何都不是最好的班级结构。但我没有意识到初始化列表有这样的限制。【参考方案2】:

你不能这样做,因为 BarBC 构造了 mOtherKey - 你不能覆盖它。

您已经分配了新值:

Bar(...) : ...
 mOtherKey=aOtherKey; 

或者创建额外的 BarBC 构造函数,其参数为 mOtherKey

【讨论】:

以上是关于在派生构造函数中访问基成员的问题的主要内容,如果未能解决你的问题,请参考以下文章

C ++:如何在派生类中定义基类构造函数,如果基构造函数具有带有私有成员的初始化列表[重复]

C++基类和派生类的构造函数

C++基类和派生类的构造函数

为啥不能在派生类的构造函数初始化列表中初始化基类的数据成员?

生成一个派生类对象时,调用基类和派生类构造函数按啥次序

在其派生类C++的构造函数中调用基类的构造函数[重复]