[英]Why can const members be modified in a constructor?
我很好奇為什么const構件可以在構造函數中修改。
初始化中是否有任何標准規則可以覆蓋成員的“常量”?
struct Bar {
const int b = 5; // default member initialization
Bar(int c):b(c) {}
};
Bar *b = new Bar(2); // Problem: Bar::b is modified to 2
// was expecting it to be an error
有任何想法嗎?
這不是修改(或賦值),而是初始化 。 例如
struct Bar {
const int b = 5; // initialization (via default member initializer)
Bar(int c)
:b(c) // initialization (via member initializer list)
{
b = c; // assignment; which is not allowed
}
};
const
數據成員不能被修改或分配,但它可以(並且需要)通過成員初始化列表或默認成員初始化程序進行初始化。
如果在同一數據成員上提供了默認成員初始值設定項和成員初始值設定項,則將忽略默認成員初始值設定項。 這就是b->b
初始化為值2
。
如果成員具有默認成員初始值設定項並且也出現在構造函數的成員初始化列表中,則忽略默認成員初始值設定項。
另一方面,默認成員初始值設定項僅在成員初始值設定項列表中未指定數據成員時生效。 例如
struct Bar {
const int b = 5; // default member initialization
Bar(int c):b(c) {} // b is initialized with c
Bar() {} // b is initialized with 5
};
添加到songyuanyao的好答案,如果你想要一個你無法在構造函數中初始化的const
數據成員,你可以使成員static
:
struct Bar {
static const int b = 5; // static member initialization
Bar(int c)
:b(c) // Error: static data member can only be initialized at its definition
{
b = c; // Error: b is read-only
}
};
在C ++ 17中,您可以通過inline
使其進一步改進:
struct Bar {
inline static const int b = 5; // static member initialization
Bar(int c)
:b(c) // Error: static data member can only be initialized at its definition
{
b = c; // Error: b is read-only
}
};
這樣您就不會遇到ODR問題。
當你這樣做時:
struct Bar {
const int b = 5; // default member initialization
...
};
您告訴編譯器使用默認構造函數執行此操作:
...
Bar() : b(5)
{}
...
無論您是否提供了默認構造函數。 當您提供默認構造函數和初始賦值時,您將覆蓋編譯器的默認賦值代碼(即b(5)
)。 當您有多個構造函數時,聲明中的默認初始化/賦值很有用,您可能會也可能不會在所有構造函數中分配const成員:
...
Bar() = default; // b=5
Bar(int x) : b(x) // b=x
Bar(double y) : /*other init, but not b*/ // b=5
...
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.