代码之家  ›  专栏  ›  技术社区  ›  Stephen

用初始化列表(C++)初始化父级受保护成员

  •  117
  • Stephen  · 技术社区  · 15 年前

    是否可以使用子类的构造函数的初始化列表初始化在父类中声明为受保护的数据成员?我不能让它工作。我可以解决这个问题,但如果我不必这么做的话那就太好了。

    一些示例代码:

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

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

    非常感谢!

    4 回复  |  直到 8 年前
        1
  •  110
  •   philsquared    15 年前

    用你描述的方式是不可能的。您必须向基类中添加一个构造函数(可能受到保护),以便将其转发。类似:

    class Parent
    {
    protected:
        Parent( const std::string& something ) : something( something )
        {}
    
        std::string something;
    }
    
    class Child : public Parent
    {
    private:
        Child() : Parent("Hello, World!")
        {
        }
    }
    
        2
  •  59
  •   WiR3D    11 年前

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

    从C++ 0X草稿中得出:

    12.6.2初始化基础和成员

    mem初始值设定项ID中的名称为 在 constructor_s class and,if not found 在这个范围内, 包含构造函数的范围 定义。[注:如果 constructor_s类包含一个成员 与直接或 类的虚拟基类,a 命名成员的mem初始值设定项ID 或基类,由单个 标识符引用类成员。 隐藏项的meminitializer-id 可以使用 限定名。“尾注”] 除非 mem initializer id将 constructor_s class,非静态数据 构造函数类的成员或 该类的直接或虚拟基础, 内存初始值设定项格式错误。

    注:强调我的。

        3
  •  12
  •   Alex Bitek Uhall    10 年前

    不能 在派生类构造函数初始化列表中初始化父类的成员。不管它们是受保护的、公开的还是其他的。

    在您的示例中,成员 something 是会员 Parent 类,这意味着它只能在的构造函数初始值设定项列表中初始化。 起源 班级。

        4
  •  0
  •   Aitor    8 年前

    也许你可以用关键字“using”来试试。

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