2016-08-24 35 views
0

爲什麼編譯器(clang)抱怨mymy未初始化,當我明確地告訴它它是一個常量值時,它保持爲50.爲什麼它允許我將其更改爲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; 
} 

奇怪的是,coliru編譯沒有hick。 http://coliru.stacked-crooked.com/a/63629c2d99bf6f43(是的,我知道將其更改爲static將解決此問題)

+0

請注意,將'mymy'傳遞給'Base'是未定義的行爲,因爲它是未初始化的。 – TartanLlama

回答

4

的標準說(§ 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不與50230初始化。您可以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)。

3

如果您使用ctor初始值設定項,那麼在類初始化時將被忽略。

要考慮到基構造與參數mymy

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

調用不正確,因爲派生類的數據成員尚未初始化。

+0

請問你可以在標準中把我和這個鏈接起來嗎? – fritzone

+0

但是'const'呢?編譯器不應該抱怨? – fritzone

+0

@fritzone很抱歉,我現在無法訪問該標準。至於const限定符,ctor還會初始化常量數據成員(靜態數據成員除外)。 –