對於下面的代碼:非靜態const數據成員的要點是什麼?
class A
{
public:
const int cx = 5;
};
這裏,CX的實例將爲A的每一個對象,它似乎是一種浪費我的創建,爲CX不能進行修改。其實,我沒有看到編譯器不應該強制const數據成員靜態的任何理由。任何人都可以向我解釋這個嗎?
對於下面的代碼:非靜態const數據成員的要點是什麼?
class A
{
public:
const int cx = 5;
};
這裏,CX的實例將爲A的每一個對象,它似乎是一種浪費我的創建,爲CX不能進行修改。其實,我沒有看到編譯器不應該強制const數據成員靜態的任何理由。任何人都可以向我解釋這個嗎?
對於所有實例,const數據成員不必相同。你可以在構造函數中初始化它。
class A
{
public:
A(int n) :cx(n) {}
const int cx;
};
int main()
{
A a1(10);
A a2(100);
}
注意,您必須在初始化程序列表中初始化它。當你進入構造函數的主體時,已經太晚了。即失敗:'A(int n){cx = n; }' – dgnuff 2014-11-03 18:53:17
其實,我看不出有任何理由爲什麼不編譯器應該推行使 一個const數據成員靜態的。
你認爲cx
可能在構造函數在運行時已知的值進行初始化 - 和A
不同實例之間變化? const
成員對他們進行分配是不可能的,但有時會讓一個無法改變其初始值的成員證明是有用的。
絕對不是最好的例子,但說明的想法:
struct Multiplier
{
const int factor;
Multiplier(int factor) : factor(factor) {}
int operator()(int val) const
{
return val * factor;
}
};
std::vector<int> vec{1, 2, 3};
std::vector<int> vec2;
int i;
std::cin >> i;
std::transform(std::begin(vec), std::end(vec),
std::back_inserter(vec2), Multiplier(i));
// vec2 contains multiples of the values of vec
如果該值被初始化爲一個常數,在你的榜樣, 它可能會更好,這是靜態的。但這並不總是 的情況;這是相當頻繁有類似:
class Matrix
{
const int myRowCount;
const int myColumnCount;
std::vector<double> myData;
// ...
public:
Matrix(int rows, int columns)
: myRowCount(rows)
, myColumnCount(columns)
, myData(rows * columns)
{
}
// ...
};
在這種情況下,const
明確表達了的 行和列在任何給定的情況下的數量不會改變。 (在 另一方面,它阻止默認賦值運算符從生成 ,這可能會也可能不是一件好事。)
使用非靜態const成員有一些限制。
假設有Employee類。 首先,雖然編譯器可以生成正確工作的拷貝構造函數,但它不能生成賦值運算符。如果一個程序創建兩個Employee對象e1和e2,則語句e1 = e2將導致編譯器診斷。這個賦值是無效的,因爲它隱含地試圖改變const成員的值。 雖然你可以通過拋棄const_ness來賦值賦值操作符,但是這不是一個好主意。
另一個限制是很難爲這個類提供一個有用的默認構造函數。如果你想創建Employee對象的數組,那麼默認的構造函數是很重要的。定義一個默認的構造函數有點棘手;要記住的主要事情是const的非靜態數據成員在構造函數的初始化列表中初始化 - 並且您必須初始化它們全部。默認構造函數必須將dob字段設置爲某個值,並且此值不能隨後更改。所以構建的陣列幾乎沒用
有可能是RAII應用程序...... – IdeaHat 2014-11-03 18:01:14
這就像說說編譯器應該堅持所有靜態數據是不變的。有些人喜歡他們的成員不變 – Creris 2014-11-03 18:02:52
您可能仍然添加其他構造函數來爲'cx'設置不同的值。 – Jarod42 2014-11-03 18:03:27