ページ 11

前方宣言したクラス・構造体の使用方法に関して

Posted: 2012年2月05日(日) 17:53
by MoNoQLoREATOR
http://fonlake.blogspot.com/2009/05/c.html

上記のサイトによると、
class A;

class B{
A a;
};
これは駄目なのだそうですが、何故なのですか?

テンプレートを間に はさめば解決するようですが、結果的には同じことなのに、どうしてコンパイルが通ったり通らなかったりするのか納得できません。

ご教授よろしくお願い致します。

Re: 前方宣言したクラス・構造体の使用方法に関して

Posted: 2012年2月05日(日) 18:16
by ISLe
class A;
↑この宣言は不完全型の宣言です。
これだとAクラスのサイズが分からないので、Aクラス型のメンバを含むBクラスのサイズを計算することもできなくてコンパイルエラーになります。
Aクラス型のポインタや参照をメンバにする場合は、実体のサイズは関係ないのでコンパイルが通ります。

C++の前方宣言(前方参照)は不完全型とは別のことなのでリンク先の記事は用語の使い方が間違っていると思います。

(追記)
テンプレートをはさんでも、Bのインスタンスを作るコードでコンパイルエラーになるので解決ではない気がします。

Re: 前方宣言したクラス・構造体の使用方法に関して

Posted: 2012年2月05日(日) 19:59
by MoNoQLoREATOR
>>ISLeさん
ありがとうございます。それはわかるのですが、

class A;

template<class T=A>
class B{
T a;
};

とした場合にコンパイルが通るのは何故ですか?

Re: 前方宣言したクラス・構造体の使用方法に関して

Posted: 2012年2月05日(日) 20:18
by h2so5
テンプレートを書いただけでは実体化されないのでエラーにはならないですが、
B<> foo;
B<A> foo;
のようにclass Aを使うことを指定したコードを書けば実体化してエラーになります。

Re: 前方宣言したクラス・構造体の使用方法に関して

Posted: 2012年2月05日(日) 22:02
by MoNoQLoREATOR
>>h2so5さん
あ。本当ですね。

ということはリンク先のサイトは『前方宣言』のみを焦点として書かれているだけであって、下記のような相互に参照し合うようなケースを想定して書かれているわけではないということですね。

コード:

class A;

template<class X=A>
class B{
	X a;
};

class A{
	B<A> b;
};

void main(){
	B<A> b;
}