的標準說(§ 12.6.2/10 ,強調的是礦):
如果一個給定的非靜態數據成員同時有默認值成員初始和MEM-初始化,指定的初始化 執行mem初始化程序,並且非靜態數據成員的默認成員初始值設定項被忽略。 [實施例:鑑於
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/使用克++不產生警告,但結果是相同的:Base
不與50
或23
但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
成員(這是在那裏你可以使用默認成員初始化沿着初始化它們唯一的地方)。
我不知道是否有與標準更明確的報價,但§ 12.6.2/7 (例子中是相當明確的,雖然):
的表達式列表或braced-init-list in mem初始化程序用於根據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);
末端示例]
最新C++ 17標準草案(N4594)。
請注意,將'mymy'傳遞給'Base'是未定義的行爲,因爲它是未初始化的。 – TartanLlama