2016-04-26 95 views
3

下面的代碼發出此警告,但它似乎工作正常,因爲A :: st和B :: st都被初始化並且實際上表示相同的字符串。根據我的理解,這是錯誤的代碼,它不應該編譯(我檢查鐺)。我想知道爲什麼VC++不會發出錯誤而不是警告?VC++警告C4356:靜態數據成員無法通過派生類初始化

#include <string> 
#include <iostream> 

class A 
{ 
public: 
    static const std::string st; 
}; 

class B : public A 
{ 

}; 

const std::string B::st = "abcd"; //warning C4356: 'A::st': static data member cannot be initialized via derived class 

int main() 
{ 
    std::cout << A::st << std::endl; // outputs "abcd" 
    std::cout << B::st << std::endl; // outputs "abcd" 
} 
+2

語言標準只是談論發佈「診斷」。它不會說如果他們被稱爲警告或錯誤(或別的東西)。 –

回答

0

從繼承的定義,一切都很好 因爲B是A加一些額外的東西,但一想起你定義了什麼! 您在類a中定義了一個靜態常量字符串。 因爲它是靜態它是全球性的,也將是同爲因爲A的,即使是直接實例A和B. 的所有實例將與「ABCD」 被初始化,如果你有一個d也從A派生,但不是從B它將包含abcd ,因爲它是靜態的,你不能夠定義一個包含「abcd」的B和一個包含「efgh」的D我還沒有嘗試,但我相當肯定你會遇到一些麻煩 if你定義

clase D :public A 
{ 
}; 
const std:string d:st = "efgh"; 

即使編譯器只告訴一個警告它可能依賴於鏈接順序什麼將是A :: st的內容。 它可能是「abcd」或「efgh」,但是d :: st將是「abcd」或B :: st將是「efgh」,因爲您無法爲B定義「abcd」而D爲「efgh」,因爲它是靜態的。