web-dev-qa-db-ja.com

typedef struct:デフォルトの初期化

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

上記の例では、my_boolがランダムにtrueまたはfalseに初期化されることを理解していますが、my_intはどうですか? my_intはデフォルトで0に初期化されると思いましたが、そうではないようです。

この方法で構造体を定義することは初期化リストと互換性がないように見えるので、my_boolmy_intをそれぞれfalseと0に初期化する最良の方法は何ですか?

11

タイプは「初期化」されません。あるタイプのobjectsのみが初期化されます。それらが初期化される方法とタイミングは、対応するオブジェクトが定義される方法と場所によって異なります。質問にオブジェクトの定義を指定しなかったため、質問自体はあまり意味がありません。必要なコンテキストが不足しています。

たとえば、タイプ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`
_

ただし、_()_初期化子を使用すると、ゼロで初期化されます。

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

foo()式を使用してタイプfooの一時オブジェクトを作成すると、その式の結果はゼロで初期化されます。

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

したがって、繰り返しになりますが、特定のケースでは、初期化の詳細は、タイプ自体ではなく、タイプのオブジェクトを作成することに依存します。タイプ自体には固有の初期化機能がなく、初期化を妨げることはありません。

20
AnT

まず、structの宣言方法は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();を実行できます。

11
Cogwheel

デフォルトのコンストラクターを実装します。

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

デフォルトのコンストラクターがあります:

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

そのコードでanyオブジェクトを作成していません。初期化はオブジェクトを作成するときに行われ、構造体を宣言する方法に特に隠れることはありません。

たとえば、次のようにブール値をfalseに初期化し、整数を0に初期化します。

foo f = { };

typdefed構造体があることに注意してください。オブジェクトを作成していません。他の人が言ったように、C++ではtypedefを省略して構造体を宣言するだけで、fooと言うだけで型を参照できます。

オブジェクトを定義するときに明示的な初期化を省略した場合、オブジェクトが名前空間スコープで定義されているか、ローカルでstaticとして定義されているか(この場合、すべてのメンバーがゼロで初期化されます)、またはクラスでない限り、初期化は行われません。それに応じて初期化を行うユーザー定義のデフォルトコンストラクタがあります。

C-wayで構造体を宣言している限り、zeromemoryを使用して正確にsizeof(foo)バイトをnullにすることができるため、すべての値がデフォルトで0になります。

C++では、必要に応じて値をデフォルト値に設定するコンストラクターを使用して構造を定義できます。

1
M. Williams

cおよびc ++は、変数をまったく初期化しません。それらには、以前に現在あったメモリ位置にたまたまあったものがすべて含まれています。これは、特に値に初期化しない限り、クラスおよび構造体のメンバー変数にも当てはまります。

1
Donnie