2017-05-19 66 views
1

比方說,我有以下代碼:(請注意,我不能改變VEC 2的聲明)正確方法來初始化成員結構

附錄A

struct Vec2 { 
    float x; 
    float y; 
}; 

class C { 
    struct Data { 
    Vec2 v1; 
    Vec2 v2; 
    int n = 0; 
    }; 
    Data _data; 

    C() : _data() {} 
}; 

這似乎正確初始化數據中的兩個Vec2結構爲零值。爲什麼會發生? C的構造函數初始化列表中的初始化是否處理了這個問題?

更正確的形式會使用統一的初始化語法嗎?

附件B

class C { 
    struct Data { 
    Vec2 v1{}; 
    Vec2 v2{}; 
    int n{}; 
    }; 
    Data _data; 

    C() {} 
}; 

這導致了我的第二個問題 - 不_data需要在構造函數的初始化列表中去,如果它的構造函數沒有參數?還是編譯器希望隱式地處理初始化?我注意到,當在圖A中使用聲明,但在VC++編譯器中忽略構造函數中的初始化程序列表時,似乎它確實如此,但在Clang上,數據似乎未初始化。

+0

我不太確定標準將如何指定此行爲,但我注意到您嘗試初始化您的成員結構的一件事是您的結構沒有聲明的默認構造函數。 –

+0

那麼構造函數是比較現代的C++統一初始值設定項的首選方法嗎? –

+0

我認爲這取決於來源內的實際需求和要求;兩者都是有效的。 –

回答

0

不知道這是否會幫助,但如果你是默認的構造函數添加到您的結構,那麼你應該能夠做一些這樣:

struct Vec2 { 
    float x; 
    float y; 
    Vec2() : x(0.0f), y(0.0f) {} 
}; 

class C { 
    struct Data { 
    Vec2 v1; 
    Vec2 v2; 
    int n; 

    Data() : v1(Vec2()), v2(Vec2()), n(0) {} 
    }; 
    Data _data; 

    C() : _data(Data()) {} 
}; 

編輯

的OP提到他不能修改Vec2所以間接可以做什麼是:

#include "Vec2" 

class MyVec2 : public Vec2 { 
public: 
    MyVec2() : x(0), y(0) {} 
}; 

然後你應該可以使用你定義的版本Vec2及其構造函數。其餘代碼將保持不變,但這可能會導致問題,因爲基類沒有自己的default constructor

+0

這會工作,但我不能修改Vec2的其他原因。我想我可以memset在數據的構造函數或說「v1 = {0};」 –

+0

@unixunited哦我看,如果你不能修改'Vec2',那麼也許你可以做的就是從'Vec2'繼承,並且定義你自己的類,這是一個衍生物,你可以創建你自己的構造函數。 –