3 回答

TA貢獻(xiàn)1780條經(jīng)驗(yàn) 獲得超4個(gè)贊
為什么我不能static
在課堂上初始化數(shù)據(jù)成員?
C ++標(biāo)準(zhǔn)只允許在類中初始化靜態(tài)常量積分或枚舉類型。這是a
允許初始化而其他人沒有的原因。
參考:
C ++ 03 9.4.2靜態(tài)數(shù)據(jù)成員
§4
如果靜態(tài)數(shù)據(jù)成員是const integer或const枚舉類型,則它在類定義中的聲明可以指定一個(gè)常量初始化器,它應(yīng)該是一個(gè)整型常量表達(dá)式(5.19)。在這種情況下,成員可以出現(xiàn)在整數(shù)常量表達(dá)式中。如果在程序中使用該成員,并且名稱空間范圍定義不包含初始化程序,則該成員仍應(yīng)在名稱空間作用域中定義。
什么是整體類型?
C ++ 03 3.9.1基本類型
§7
類型bool,char,wchar_t以及有符號和無符號整數(shù)類型統(tǒng)稱為整數(shù)類型.43)整數(shù)類型的同義詞是整數(shù)類型。
腳注:
43)因此,列舉(7.2)不是不可或缺的;?但是,枚舉可以提升為int,unsigned int,long或unsigned long,如4.5中所述。
解決方法:
您可以使用枚舉技巧初始化類定義中的數(shù)組。
class?A? { ????static?const?int?a?=?3; ????enum?{?arrsize?=?2?}; ????static?const?int?c[arrsize]?=?{?1,?2?};};
為什么標(biāo)準(zhǔn)不允許這樣做?
Bjarne?在這里恰當(dāng)?shù)亟忉屃诉@一點(diǎn):
類通常在頭文件中聲明,并且頭文件通常包含在許多翻譯單元中。但是,為避免復(fù)雜的鏈接器規(guī)則,C ++要求每個(gè)對象都有唯一的定義。如果C ++允許將需要作為對象存儲(chǔ)在內(nèi)存中的實(shí)體的類內(nèi)定義,則該規(guī)則將被破壞。
為什么只static const
允許整數(shù)類型和枚舉進(jìn)行類內(nèi)初始化?
答案隱藏在Bjarne的引言中,仔細(xì)閱讀,
“C ++要求每個(gè)對象都有一個(gè)唯一的定義。如果C ++允許將需要作為對象存儲(chǔ)在內(nèi)存中的實(shí)體的類內(nèi)定義,那么該規(guī)則就會(huì)被破壞?!?/em>
請注意,只有static const
整數(shù)可以被視為編譯時(shí)常量。編譯器知道整數(shù)值不會(huì)隨時(shí)改變,因此它可以應(yīng)用自己的魔法并應(yīng)用優(yōu)化,編譯器只是內(nèi)聯(lián)這樣的類成員,即它們不再存儲(chǔ)在內(nèi)存中,因?yàn)樾枰鎯?chǔ)在內(nèi)存中被刪除,它給這些變量提供了Bjarne提到的規(guī)則的例外。
值得注意的是,即使static const
整數(shù)值可以具有類內(nèi)初始化,也不允許采用這些變量的地址。如果(并且僅當(dāng))它具有類外定義,則可以獲取靜態(tài)成員的地址。這進(jìn)一步驗(yàn)證了上面的推理。
允許枚舉這是因?yàn)槊杜e類型的值可以在期望int的位置使用。看上面的引文
這在C ++ 11中是如何變化的?
C ++ 11在一定程度上放寬了限制。
C ++ 11 9.4.2靜態(tài)數(shù)據(jù)成員
§3
如果靜態(tài)數(shù)據(jù)成員是const文字類型,則其在類定義中的聲明可以指定一個(gè)大括號或大小為初始化器,其中作為賦值表達(dá)式的每個(gè)initializer子句都是一個(gè)常量表達(dá)式。可以在類定義中使用if?聲明文字類型的靜態(tài)數(shù)據(jù)成員,其聲明應(yīng)指定一個(gè)大括號或者等于初始化器,其中每個(gè)initializer子句都是賦值表達(dá)式
constexpr specifier;
是一個(gè)不變的表達(dá)。[注意:在這兩種情況下,成員可能會(huì)出現(xiàn)在常量表達(dá)式中。-end note]如果在程序中使用該成員,并且命名空間作用域定義不包含初始化程序,則該成員仍應(yīng)在命名空間作用域中定義。
此外,C ++ 11?將允許(§12.6.2.8)在聲明它(在其類中)的地方初始化非靜態(tài)數(shù)據(jù)成員。這將意味著很容易的用戶語義。
請注意,這些功能尚未在最新的gcc 4.7中實(shí)現(xiàn),因此您可能仍會(huì)遇到編譯錯(cuò)誤。

TA貢獻(xiàn)1827條經(jīng)驗(yàn) 獲得超4個(gè)贊
這似乎是舊時(shí)簡單連接器的殘留。您可以在靜態(tài)方法中使用靜態(tài)變量作為變通方法:
// header.hxx#include <vector>class Class {public: static std::vector<int> & replacement_for_initialized_static_non_const_variable() { static std::vector<int> Static {42, 0, 1900, 1998}; return Static; }};int compilation_unit_a();
和
// compilation_unit_a.cxx#include "header.hxx"int compilation_unit_a() { return Class::replacement_for_initialized_static_non_const_variable()[1]++;}
和
// main.cxx#include "header.hxx"#include <iostream>int main() { std::cout << compilation_unit_a() << Class::replacement_for_initialized_static_non_const_variable()[1]++ << compilation_unit_a() << Class::replacement_for_initialized_static_non_const_variable()[1]++ << std::endl;}
建立:
g++ -std=gnu++0x -save-temps=obj -c compilation_unit_a.cxx g++ -std=gnu++0x -o main main.cxx compilation_unit_a.o
跑:
./main
事實(shí)上這一點(diǎn)(一致地,即使類定義包含在不同的編譯單元中),也表明今天的鏈接器(gcc 4.9.2)實(shí)際上足夠智能。
搞笑:0123
在手臂和3210
x86上打印。

TA貢獻(xiàn)1845條經(jīng)驗(yàn) 獲得超8個(gè)贊
我認(rèn)為這是為了防止你混淆聲明和定義。(想想如果將文件包含在多個(gè)位置可能會(huì)出現(xiàn)的問題。)
- 3 回答
- 0 關(guān)注
- 1020 瀏覽
添加回答
舉報(bào)