C++クラス内メンバクラスの初期化について

「C++の関数が多重継承している」という勘違いから正しい理解に到るまでの自分用備忘録。
1
Minagawa Takuya @takmin

C++でclassA::functionA(): functionB(){}なんて表現を見つけたんだけど、初めて見た。関数の継承???

2011-04-28 19:15:36
Minagawa Takuya @takmin

ちなみに、その同じソースの中で classA::functionA():functionB(),functionC(),functionD(){}という多重継承っぽい表現見つけたんだけど、一般的なの?ただの僕の知識不足?

2011-04-28 19:18:17
藤本直明/FUJIMOTO Naoaki @naokiring

コンストラクタでは無いんですよね?、コンストラクタ初期化子以外でそういう表現みたことないっすね…。うーん…。 RT @takmin: C++でclassA::functionA(): functionB(){}なんて表現を見つけたんだけど、初めて見た。関数の継承???

2011-04-28 21:17:00
idojun @idojun

@takmin 基底クラスの引数付きコンストラクタの呼び出しですね.

2011-04-28 21:18:28
Minagawa Takuya @takmin

@naokiring はい、コンストラクタじゃなく、普通のメンバ関数でした。

2011-04-28 21:18:31
藤本直明/FUJIMOTO Naoaki @naokiring

@takmin functionB()は、どういう関数なんでしょうか?(継承元に存在するとか…)

2011-04-28 21:20:33
Minagawa Takuya @takmin

. @takmin @idojun すいません、ちゃんと確認したら仰るとおりfunctionA()はコンストラクタでした。ただ、functionB()は基底クラスではなく、自分自身のメンバ関数です。

2011-04-28 21:22:57
Minagawa Takuya @takmin

こうでした。classA::classA(): functionB(), functionC()みたいになっていて、functionBとfunctionCというのが、classAのメンバ変数クラスのコンストラクタでした。っていうか、ますます何をやっているのかわからない。。。

2011-04-28 21:28:39
藤本直明/FUJIMOTO Naoaki @naokiring

@takmin クラス内クラスのコンストラクタってことですか?

2011-04-28 21:30:14
Minagawa Takuya @takmin

@naokiring そうです。クラスA内にメンバとしてクラスBのインスタンスがあって、そのコンストラクタを呼び出してるっぽいんですが、やっぱり何か読み間違えてるのかなあ。。。

2011-04-28 21:31:32
藤本直明/FUJIMOTO Naoaki @naokiring

@takmin クラス内クラスの名前と、そのインスタンスの名前が同じなら、そういう状態になりえますが…。 http://twitpic.com/4qi465

2011-04-28 21:33:25
拡大
藤本直明/FUJIMOTO Naoaki @naokiring

@idojun @takmin まぁ、クラス内クラスじゃなくても、単にクラス名とインスタンス(メンバ変数)名が同じになってる(かぶってる)可能性くらいしか思い浮かばないですね…。

2011-04-28 21:42:41
Minagawa Takuya @takmin

こんな感じでした。http://twitpic.com/4qi81j RT @naokiring: @takmin クラス内クラスの名前と、そのインスタンスの名前が同じなら、そういう状態になりえますが…。 http://twitpic.com/4qi465

2011-04-28 21:43:30
拡大
拡大
藤本直明/FUJIMOTO Naoaki @naokiring

@takmin それは、そのメンバ変数を初期化します、っていう意味ですね。メンバ変数のコンストラクタに引数がない場合は、特に書かなくてもいいんですが…。

2011-04-28 21:44:27
Minagawa Takuya @takmin

. @idojun @naokiring なるほど。実際はメンバ変数に引数を渡してました。これって、コンストラクタ内部でメンバ変数のコンストラクタ呼び出して初期化するのと何が違うんでしょう?

2011-04-28 21:46:18
みやびあーつ @miyabiarts

@takmin メンバ変数としたクラスのコンストラクタが引数なしであれば、ここで言うA::A() : b(), c(){}は省略してA::A(){}と等価で、引数付きのコンストラクタだったならば、ここで初期化しておかないとエラーが起きます。

2011-04-28 21:46:30
藤本直明/FUJIMOTO Naoaki @naokiring

@takmin @idojun クラスBのコンストラクタが複数ある場合には、どれを使って初期化するのかを明示する方法はこれしかないです。他にも違いがあったような気がしますが…。

2011-04-28 21:47:53
Minagawa Takuya @takmin

. @sugar_fever @miyabiarts はい、b()とc()に引数渡してました。継承みたいな書き方されてるけど、別物なんですね。

2011-04-28 21:49:52
idojun @idojun

@naokiring @naokiring あとは,constなメンバの初期化とか,

2011-04-28 21:51:19
みやびあーつ @miyabiarts

@takmin コンストラクタの後の「:」は継承とは関係なく、あくまで初期化で、その初期化のついでに継承していた場合は仮想テーブル引いて基底クラスのコンストラクタを呼び出しているので、初期化には変わりません。

2011-04-28 21:51:47
藤本直明/FUJIMOTO Naoaki @naokiring

@takmin @idojun さっき皆川さんが書いてた例でも、Aのコンストラクタ初期化子(コロンの後に書くやつ)で初期化しないと、「Bのコンストラクタを使った初期化」は出来ないですよね。そのあとでコンストラクタ内で初期化しても二度手間というか…。

2011-04-28 21:51:55
Minagawa Takuya @takmin

@naokiring @idojun あ、なるほど。A()の中に入っちゃうと、b、cのコンストラクタ呼び出しは手遅れなわけですね。(こういう理解でいいのかな?)

2011-04-28 21:55:31