質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

4回答

3946閲覧

[c++]インスタンス変数定義の初期値記述を省略した際の初期値は?

clateratail

総合スコア24

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2020/02/02 19:58

編集2020/02/02 23:27

c++

1Class B{ 2 int i; 3} 4class A{ 5 B b; 6 B*ptrB; 7} 8 9A a; 10main(){ 11 a.b.i; ///0 12 a.ptrB; ///NULL 13 14 A localA; 15 localA.b.i; ///0 16 localA.ptrB; ///NULL 17} 18 19

このような理解で問題ないでしょうか?
あるいは明示的に
int i=0;
B*ptrB=NULL;
等、記述しておくべきですか?よろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答4

0

こんにちは。

静的領域は全てゼロ初期化されるので以下は正しい筈です。

a.b.i; ///0
a.ptrB; ///NULL

動的領域の変数はゼロ初期化されないので以下は間違っている筈です。

localA.b.i; ///0
localA.ptrB; ///NULL

int型等の基本型やenum型は、ゼロ初期化を除き自動的には初期化されません。クラス型は初期化を省略するとデフォルト・コンストラクタで初期化されます。

ゼロ初期化のルールは非常に複雑ですし、実行されない時もあるので、原則としてゼロ初期化には頼らない方が確実と思います。そのためには、コンストラクタを定義して、全ての基本型やenum型メンバ変数を初期化するのが望ましいです。

投稿2020/02/03 02:56

編集2020/02/03 03:07
Chironian

総合スコア23272

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

clateratail

2020/02/03 22:47

なんと実行されない時もあるのですか 助言の通りコンストラクタの実装は省略しないことにしました 回答ありがとうございました
guest

0

ベストアンサー

クラスAはトリビアルなデフォルトコンストラクタです。領域確保されるだけで何もしません。ですので、自動変数であるlocalAの中身は不定です。何になるのかは環境や実行時依存であり、予測不可能です。対して、静的変数であるaゼロ初期化されます。数値は0になりますし、ポインタはnullptrになります。どちらの場合もクラスBのオブジェクトが作られることはありません。

この動作はCの構造体とほぼ一緒です。

投稿2020/02/02 22:25

編集2020/02/03 09:07
raccy

総合スコア21739

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

clateratail

2020/02/02 23:14

回答ありがとうございます A localA=A(); とすれば、数値は0、ポインタはnullptrとなりますでしょうか?
SaitoAtsushi

2020/02/03 00:22

なりません。 A() で生成されるオブジェクトのメンバは初期化されていないので、それをコピーしたところで意味のある値にはなりません。 更に RVO でコピーが抑制されると A localA; としたのと全く同じです。
kazuma-s

2020/02/03 04:48

A localA = A(); の場合は、初期化されます。 規格の項目を検索するのが面倒なので、確認コードを示すだけにします。 #include <iostream> using namespace std; struct B {   int i; }; struct A {   B b;   B *ptrB; }; void print(const A *x); int main() {   A a1;   A a2 = A();   print(&a1);   print(&a2);   A *p1 = new A;   A *p2 = new A();   print(p1);   print(p2);   delete p1;   delete p2; } void print(const A *p) {   cout << ".b = " << p->b.i << ", .ptrB = " << p->ptrB << endl; }
raccy

2020/02/03 09:27

> A localA=A(); `A()`自体がリンク先の(2)であるゼロ初期化に該当し、それは値初期化(下記リンク)の一種です。 https://ja.cppreference.com/w/cpp/language/value_initialization それをコピーコンストラクタ(C++11以上ならムーブコンストラクタ)になりますが、ほとんどの場合は最適化によってC++11以上で`A localA{};`と書いた場合と同じ動作になります(つまり、実際はコピーもムーブもしない)。詳しくはリンク先のノートなどを見てください。
SaitoAtsushi

2020/02/03 10:21

完全に状況を思い違いしてました。 上の書き込みは忘れてください。
clateratail

2020/02/03 22:43

自分が想像していた以上に初期値関連が複雑だという事が分かりました リンク先value_initializationの例事が非常に良く分かりました 回答ありがとうございました
guest

0

あるいは明示的に

int i=0;
B*ptrB=NULL;
等、記述しておくべきですか?

デフォルトコンストラクタを用意しておきましょう。そうすれば、宣言する場所に関わらず同じ初期値をセットできます。

投稿2020/02/02 23:00

maisumakun

総合スコア146018

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

clateratail

2020/02/02 23:21

すみません。質問の仕方を間違えたかもしれません。 インスタンス変数の宣言部の"初期値を省略"した場合の挙動(代入される初期値)が知りたい事でした。 明示的に記述というのは class A{ B*ptrB=NULL; } という意味でした。 これは、グローバル変数であれば、NULLを記述してもしなくても同じ挙動(ゼロ初期化)でしょうか。
cateye

2020/02/03 03:01 編集

clateratailさん そのへんについても、上記https://ja.cppreference.com/w/cpp/language/initialization に書かれています。 デフォルト初期化→https://ja.cppreference.com/w/cpp/language/default_initialization も参考に
clateratail

2020/02/03 22:45

リンク先value_initializationに非常に分かりやすい事例がありました 回答ありがとうございました
maisumakun

2020/02/03 22:54

他の方の回答にもありますが、「宣言の仕方によって正しい初期化がなされない危険がある」クラスは、実際のコードで使うには怖いです。 組み込みなどで極限まで実行コードを削りたい状況でもないのでしたら、デフォルトコンストラクタで初期化しておく、という実装をすれば、「どこで初期化されるか」考えずに済むようになります。
guest

0

質問に有るような事を実際に試した訳ではないですが、ローカルで使用する(可能性が有る)クラスは“初期化子リスト”で初期化するようにしています。

投稿2020/02/02 20:30

cateye

総合スコア6851

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

clateratail

2020/02/02 23:12

回答ありがとうございました
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問