C++ 03 Style
#include "fileWithStruct.h"
/* say the contents were
struct foo
{
int foo1;
float foo2;
};
*/
class myClass
{
public:
int val;
foo bar;
// since foo is a POD-struct (a.k.a C struct), no constructor would be present
// however bar() will zero-initialize everything in the struct
myClass() : val(), bar()
{
}
};
parentheses following bar
matters. Zajrzyj na stronę value and zero-initialization, aby zrozumieć, dlaczego to działa. Należy zauważyć, że dodając konstruktora do myClass
, stworzyliśmy go jako typ inny niż POD. Aby obejść ten problem, można zachować myClass
jako kruszywo i napisać:
class myClass
{
public:
int val;
foo bar;
};
int main()
{
myClass zeroed_obj = { };
myClass inited_obj = { 2, {0, 1.0f} };
myClass partially_inited_obj = { 2 }; // equivalent to {2, {}}; which would zero all of myClass::bar
myClass garbage_obj; // warning: when left uninitialized, every member without a constructor will end up with garbage value
}
C++ 11 Style
class myClass
{
public:
// default member initializations
int val = { }; // zero-initialization
foo bar = { 0, 0.0f }; // aggregate-initializing foo here, just giving { } will zero all of myClass::bar
// should you want to receive an element from the constructor, this can be done too
// aggregate initializing a struct in constructor initialization list is allowed from C++11 onwards
// in C++03, we would've resorted to just setting the member of bar inside the constructor body
myClass(int _foo1) : bar{_foo1, 0.f}, val{}
{
}
// since we've a non-default constructor, we've to re-introduce the default constructor
// if we need the above in-class initialization to work
myClass() = default;
};
Tutaj używamy C++ 11 na uniform initialization syntax. Jednakże, robiąc to, myClass
staje się typem nie POD; Inicjowanie członków jest podobne do dodawania konstruktora do klasy, co powoduje, że myClass
jest klasą niebanalną, ale standardową. Zgodnie z C++ 11 dla klasy, która ma być POD, powinna być zarówno trywialna, jak i standardowa. Zamiast tego zachowuje się
#include "fileWithStruct.h"
#include <type_traits>
#include <iostream>
class myClass
{
public:
int val;
foo bar;
};
int main()
{
myClass obj { }; // initializes val, bar.foo1 and bar.foo2 to 0
myClass m { 0, {1, 2.0f} }; // initilizes each member separately
std::cout << std::is_pod<myClass>::value << std::endl; // will return 1
}
jako czujnik POD
myClass
.
Aby dowiedzieć się więcej o agregatach i czujnikach POD, przeczytaj artykuł this excellent post.
Nie masz n eed do sat 'struct foo bar;' w C++ 03 lub C++ 11, po prostu 'foo bar;' zrobi. Również w C++ 11 możesz zainicjować 'bar' w punkcie deklaracji. – juanchopanza
Uzgodniono, poprawiono w odpowiedzi. To jest stara składnia deklaracji struktury obiektów w stylu C. – legends2k
OP wyraźnie wspomina o 'foo' znajdującym się w nagłówku C, więc dodanie konstruktora do niego nie jest opcją. (I proszę nie naprawiaj tego, wstawiając '#ifdef __cplusplus' do nagłówka C) –