【问题标题】:Initialize parent's protected members with initialization list (C++)使用初始化列表初始化父级的受保护成员 (C++)
【发布时间】:2011-01-18 10:39:06
【问题描述】:

是否可以使用子类的构造函数的初始化列表来初始化在父类中声明为受保护的数据成员?我无法让它工作。我可以解决它,但如果我不必这样做会很好。

一些示例代码:

class Parent
{
protected:
    std::string something;
};

class Child : public Parent
{
private:
    Child() : something("Hello, World!")
    {
    }
};

当我尝试这个时,编译器告诉我:“类 'Child' 没有任何名为 'something' 的字段”。这样的事情可能吗?如果有,语法是什么?

非常感谢!

【问题讨论】:

    标签: c++ inheritance constructor initialization-list


    【解决方案1】:

    按照你描述的方式是不可能的。您必须向基类添加一个构造函数(可能受到保护)才能转发它。比如:

    class Parent
    {
    protected:
        Parent( const std::string& something ) : something( something )
        {}
    
        std::string something;
    }
    
    class Child : public Parent
    {
    private:
        Child() : Parent("Hello, World!")
        {
        }
    }
    

    【讨论】:

    • 这正是我已经想出的解决方法。至少现在我不用担心能不能做到。 :)
    【解决方案2】:

    当编译器遇到初始化列表时,派生类对象尚未形成。直到那时还没有调用基类构造函数。只有在调用了基类构造函数之后,something 才会出现。因此问题。当您不显式调用基类构造函数时,编译器会为您执行此操作(通过为基类生成适当的普通构造函数)。这会导致 something 成员被默认初始化。

    来自 C++0x 草案:

    12.6.2 初始化基和成员

    2 mem-initializer-id 中的名称是 在范围内查找 构造函数的类,如果没有找到 在那个范围内,在 包含构造函数的作用域 定义。 [注:如果 构造函数的类包含一个成员 与直接或 类的虚拟基类,a mem-initializer-id 命名成员 或基类,由单个 标识符是指类成员。 隐藏的 meminitializer- id 基类可以使用 限定名称。 ——尾注] 除非 mem-initializer-id 命名 构造函数的类,非静态数据 构造函数类的成员或 该类的直接或虚拟基础, mem-initializer 格式不正确。

    注意:强调我的。

    【讨论】:

    • 感谢您指出“为什么”。完全有道理。我已经离开 C++ 太久了... :)
    【解决方案3】:

    不能在派生类构造函数初始化列表中初始化父类的成员。它们是受保护的、公开的还是其他任何东西都没有关系。

    在您的示例中,成员somethingParent 类的成员,这意味着它只能在Parent 类的构造函数初始化列表中进行初始化。

    【讨论】:

      【解决方案4】:

      也许您可以使用关键字“using”以这种方式尝试

      class Parent
      {
      
      protected:
      std::string something;
      };
      
      class Child : public Parent
      {
      
      private:
      using Parent::something;
      Child()
      {
          something="Hello, World!";
      }
      };
      

      【讨论】:

        猜你喜欢
        • 2011-12-01
        • 2015-06-30
        • 2015-04-27
        • 1970-01-01
        • 1970-01-01
        • 2011-07-14
        • 2019-09-10
        • 1970-01-01
        • 2015-09-25
        相关资源
        最近更新 更多