【问题标题】: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 的事实有关?

【问题讨论】:

    标签: c++ inheritance constructor


    【解决方案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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-01-21
      • 1970-01-01
      • 1970-01-01
      • 2011-02-24
      • 1970-01-01
      • 1970-01-01
      • 2013-02-04
      相关资源
      最近更新 更多