2010-06-30 107 views
10
typedef struct foo 
{ 
    bool my_bool; 
    int my_int; 
} foo; 

在上面我的理解是my_bool將被隨機初始化爲真或假,但怎麼樣my_int的例子嗎?我認爲my_int將默認初始化爲0,但似乎並非如此。typedef結構:默認初始化

以這種方式定義結構似乎是不符合初始化列表等什麼是初始化分別my_boolmy_int虛假和0的最佳方式?

+2

你確定這是C++嗎? – 2010-06-30 22:00:12

+0

@Noah:C中沒有'bool',但是無論如何你確實有一點。 – sbi 2010-06-30 22:07:53

+2

「my_bool將被隨機初始化爲真或假」 - 也許,但不一定。未初始化意味着根本沒有初始化。根據您使用的實現方式,允許該對象的內存,例如包含陷阱或其他無效值。不同之處在於,如果您採用「隨機」布爾值「x」(true或false),則「x ||」標準保證x!是真實的。如果你採用一個未初始化的布爾值「y」,那麼標準對y ||的結果沒有任何說明!y'。這可能是真實的,錯誤的,或導致崩潰或任何其他行爲。 – 2010-06-30 22:40:45

回答

18

類型不會「初始化」。只有對象被初始化。初始化的方式和時間取決於相應對象的定義方式和位置。你沒有在你的問題中提供任何對象的定義,所以你自己的問題本身沒有多大意義 - 它缺乏必要的上下文。

例如,如果你定義foo

static foo foo_object; // zeros 

類型的靜態對象,因爲與靜態時間所有對象都自動初始化爲零它會自動初始化爲零。

如果定義foo類型的自動對象沒有初始化,它將保持未初始化

void func() 
{ 
    foo foo_object; // garbage 
} 

如果定義foo類型的自動物體與聚合初始值,它將被按照該初始化初始化

void func() 
{ 
    foo foo_object1 = { 1, 2 }; // initialized 
    foo foo_object2 = {}; // initialized with zeros 
} 

如果用new分配你的對象,並提供沒有初始化,它將保持未初始化

foo *p = new foo; // garbage in `*p` 

但是如果你使用的()初始化,這將是零initialzed

foo *p = new foo(); // zeros in `*p` 

如果您創建使用foo()表達式類型foo的臨時對象,表達式的結果將是零初始化

bool b = foo().my_bool; // zero 
int i = foo().my_int; // zero 

因此,再次,在特定情況下的初始化細節取決於現在您創建類型的對象,而不是你喜歡的類型本身。您的類型本身沒有固有的初始化設施,並且不會以任何方式干擾初始化。

+0

我通常只是通過'foo a_foo'來創建一個自動對象;' ..然後跟進'a_foo.my_bool = true;'對於較大的結構,我並不總是想手動設置5-6個成員。 – 2010-06-30 23:44:37

11

首先,該結構被宣佈的方法是在C的風格在C++中,你應該只是做:

struct foo 
{ 
    bool my_bool; 
    int my_int; 
}; 

在C和C++,初始化爲分配一個單獨的步驟。如果你總是希望初始化結構的成員,像這樣使用缺省初始化的語法:

struct foo 
{ 
    bool my_bool{}; 
    bool my_int{}; 
}; 

在++,你需要手動編寫初始化所有成員一個默認的構造舊版本的C(較新的語法以上這只是糖):

struct foo 
{ 
    foo() : my_bool(), my_int() { } 
    bool my_bool; 
    int my_int; 
}; 

由於@sbi筆記,如果你想手動初始化結構,即使沒有默認構造函數,你可以做foo myFoo = foo();

+1

+1。除了C風格之外,我甚至會說即使在C語言中也是一種糟糕的風格(儘管它很常見)。 Peter van der Linden在這本醜陋的魚類書中深入探討了這一點,但是寫* struct foo *並不難,並且爲類型提供了一個一致的名稱,它更容易轉發declare(而不是像* struct st_foo *和a * foo * typedef)。 – stinky472 2010-07-01 02:58:51

1

只要你聲明的結構一個 C路,您可以使用zeromemory確切爲null,因此將所有值默認爲0

在C++中,你可以用一個構造函數來定義你的結構,如果需要,你可以將你的值設置爲一些默認值。

+2

如果稍後有人添加'double my_fpn;',那麼在一個實現中,所有位設置爲零的double都不是有效的浮點數。 – sbi 2010-06-30 22:03:12

1

c和C++根本不初始化變量。它們包含了他們之前在內存中發生的任何事情。這也適用於類和結構中的成員變量,除非您專門將它們初始化爲一個值。

+0

這不適用於C++。一個簡單的'std :: string s;'必然會初始化's'。 – sbi 2010-06-30 22:05:54

+0

std :: string創建一個對象並調用它的構造函數並顯式初始化它。這可能是技術上的差異,但我的發言仍然正確。在這種情況下,他可以爲他的結構創建一個縮攏器並獲得相同的行爲。這是否意味着它正在自動初始化?不,不是。 – Donnie 2010-06-30 22:14:10

+0

您不必將其初始化爲一個值,例如'int i = int();'調用int的「默認構造函數」,因此將i初始化爲默認值0 – smerlin 2010-06-30 22:30:18

4

有一個默認的構造函數:

struct foo { 
    foo() : my_bool(false), my_int(0) {} 
    bool my_bool; 
    int my_int; 
}; 
10

實現一個默認的構造函數:

typedef struct foo 
{ 
    foo() 
    : my_bool(false), my_int(0) 
    { 
     // Do nothing 
    } 
    bool my_bool; 
    int my_int; 
} foo; 
+2

我認爲這要好得多,這取決於數據成員的隱式初始化。最特別的是,如果您碰巧正在編寫平臺中立代碼。即使您希望所有編譯器的行爲完全相同,但明確您的意圖仍然很好。它有助於可讀性,可維護性,並幫助那些追隨你的人。 – 2010-07-01 02:19:46

2

沒有創建任何對象中的代碼。初始化是在創建對象時完成的,並且不是由您聲明結構的方式所特有的。

例如,下面的初始化布爾值false和整數0

foo f = { }; 

請注意,您剛纔typdefed你的結構。你還沒有創建一個對象。像其他人一樣,你可以省略C++中的typedef,只聲明結構,並且只要說foo就可以引用該類型。

如果省略明確的初始化當你定義一個對象,那麼可以肯定,除非該對象在命名空間範圍內定義或定義爲static本地(在這種情況下,所有成員都初始化爲零)沒有初始化完成或類有一個用戶定義的默認構造函數,相應地進行初始化