繁体   English   中英

在类中常量成员的初始化

[英]In class initialization of constant member

当我专门告诉mymy为常数值并保持50时,为什么编译器(clang)抱怨mymy未初始化。为什么当我仍然告诉他mymy其更改为23时,为什么呢?保持不变?

#include <iostream>

class Base
{
public:

    Base(int y) : my(y) {std::cout << "Base:" << my << std::endl;}
private:
    int my;
};

class Derived : public Base
{
public:
    Derived() : Base(mymy), mymy(23) {std::cout << "Derived:" << mymy << std::endl;}


private:

    const int mymy = 50;
};

int main()
{
    Derived a;
}

奇怪的是,大肠菌科病菌没有山ick。 http://coliru.stacked-crooked.com/a/63629c2d99bf6f43 (是的,我知道将其更改为static将解决此问题)

该标准说(§12.6.2/ 10 1 ,重点是我的):

如果给定的非静态数据成员同时具有默认成员初始化程序和mem-initializer ,则将执行由mem-initializer指定的初始化 ,并且将忽略非静态数据成员的默认成员初始化程序 [ 示例:已知

 struct A { int i = /* some integer expression with side effects */ ; A(int arg) : i(arg) { } // ... }; 

A(int)构造函数将简单地将i初始化为arg的值,并且不会发生i的默认成员初始化器中的副作用。 —末例 ]

http://coliru.stacked-crooked.com/使用不会产生警告的g ++,但结果是相同的: Base不是用5023初始化,而是用0初始化。 您可以通过在mymy之前添加另一个属性来获得怪异的行为:

class Derived: public Base {
  public:
  Derived() : Base(mymy), mymymy(mymy), mymy(23) {
      std::cout << "Derived:" << mymy << std::endl;
      std::cout << "Derived:" << mymymy << std::endl;

  }
  int mymymy;
  const int mymy = 50;
};

来自coliru的输出:

Base:4197208
Derived:23
Derived:4197208
Main:23

但是,如果在mymy之后添加属性:

class Derived : public Base {
  public:
  Derived() : Base(mymy), mymy(23) {
      std::cout << "Derived:" << mymy << std::endl;
      std::cout << "Derived:" << mymymy << std::endl;

  }
  const int mymy = 50;
  int mymymy= mymy;

};

将使用您在构造函数的member-initializer-list中提供的值:

Base:0
Derived:23
Derived:23
Main:23

关于const限定:您始终可以在const的member-list-initializer中初始化const成员(这是可以与默认成员初始化程序一起对其进行初始化的唯一位置)。

我不知道标准中是否有更明确的报价单,但是§12.6.2/ 7 1 (示例非常明确):

mem初始化程序中expression-listbraced-init-list用于根据直接初始化的8.5初始化规则来初始化指定的子对象(或在委派构造函数的情况下,是完整的类对象)。 [ 示例:

 struct B1 { B1(int); /* ... */ }; struct B2 { B2(int); /* ... */ }; struct D : B1, B2 { D(int); B1 b; const int c; }; D::D(int a) : B2(a+1), B1(a+2), c(a+3), b(a+4) { /* ... */ } D d(10); 

—末例 ]


1最新的C ++ 17标准草案(N4594)。

如果使用ctor初始化器,则在类中将忽略初始化。

考虑到带有mymy参数的基本构造函数的mymy

Derived() : Base(mymy), mymy(23) {std::cout << "Derived:" << mymy << std::endl;}

是错误的,因为派生类的数据成员尚未初始化。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM