2017-08-09 62 views
1

比方說,我有這樣的結構:自撐初始化

struct MyStruct { 
    int field1; 
    char *field2; 
    MyStruct(int a, char* b): field2(b) { 
     field1 = doStuff(a); 
    } 
    MyStruct(int a): MyStruct(a, nullptr) {} 
    ~MyStruct(); 
} 

據我知道這是不是一個集合體,我有一些構造函數。

我想達到的目標是使用大括號初始化在自定義的方式,這意味着使用這樣的代碼:

MyStruct x = { 1, "string" }; 

這隱式調用適當的構造函數(第一個在此案件)。

這有可能以任何方式嗎?

+0

[initializer_list(http://en.cppreference.com/w/cpp/utility/initializer_list)?順便說一句...在這種特殊情況下,您可以通過使用[默認參數](http://en.cppreference.com/w/cpp/language/default_arguments)來減少代碼。 – user1810087

+3

如果你只是使用'const char *'而不是'char *',它只是按原樣編譯。問題是什麼? – SergeyA

回答

7

你快到了。 MyStruct x = { 1, "string" };被稱爲複製列表初始化。它會試圖建構從從支撐,初始化列表

你的問題是提供的參數可用構造一個MyStruct是你的構造需要char*"string"const char[N]可衰變成const char*,不一個char*。所以做出這樣的轉變

struct MyStruct { 
    int field1; 
    const char* field2; 
    MyStruct(int a, const char* b): field2(b) { 
     field1 = a; 
    } 
    MyStruct(int a): MyStruct(a, nullptr) {} 
    ~MyStruct() {} 
}; 

然後

MyStruct x = { 1, "string" }; 

將工作的事情。如果你想使這個多一點防彈你可以改變field2是一個std::string和使用

struct MyStruct { 
    int field1; 
    std::string field2; 
    MyStruct(int a, const std::string& b): field1(a), field2(b) {} 
    MyStruct(int a): MyStruct(a, "") {} 
    ~MyStruct() {} 
}; 
+0

如果你需要'field2'是可變的,你需要使用'std :: string'或者手動複製字符串。即使你不需要'const',你也應該使用'std :: string'或者C++ 17'std :: string_view'。 –

+0

@DanielH''string_view'好東西。這是不可變的,所以它是一個'const char *',它沒有複製它,因爲我認爲它不重要。我錯了!需要說明的是,如果'field1'也是常量(然後我在構造函數中有一個'const int a',那麼所有東西都會繼續工作嗎? – Fylax

+2

您可以使用'const'值初始化一個非'contst'變量。這裏是你不能用'指向* const *'的指針來初始化一個指向非''constst *'的*指針,因爲那麼你可以通過創建的指針來改變這個值。 –