- - PR -
VC++2005(CLI)でclass Aとclass Bを呼び合うコードの書き方
1
投稿者 | 投稿内容 | ||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2007-01-22 17:34
お世話になってます。
現在、VC++2005でアプリケーションを開発しています。 VB.NETやC#、Javaなどのオブジェクト指向言語での開発経験はあります。 C++での開発もそれなりにあります。 が、いまさらこんなことで質問するのも恥ずかしいのですが、C++の書き方で 行き詰っています。 というもの、以下のコードのように、class A型の定義の中にはclass B型の変数が、 class B型の定義の中にはclass A型の変数が使われているようなとき、C++では どのようにコードを書けばいいのかわかりません。 単純に、以下のようにコードを書くと、どちらかが型宣言できていないとなって、 コンパイルエラーになります。 VB.NETやC#、Javaではこんなこと意識したこともなかったのですが・・・。
上記は、わかりやすいように両者ともクラスとしましたが、今実際には 片側がインターフェースとなっているコードを書きたいのですが・・・。 googleで調べたのですが、検索キーワードが思い浮かばず、断念してしまいました。 よろしくお願いします。 | ||||||||||||||||||||||||||||
|
投稿日時: 2007-01-22 17:43
参考:相互参照(循環参照)するクラス
http://forums.microsoft.com/MSDN-JA/ShowPost.aspx?PostID=920240&SiteID=7 追記 純粋なC++でも考え方は同じです。 参考:includeについて http://forums.belution.com/ja/vc/000/389/49s.shtml の #00038950のtetrapodさんのおっしゃることが全て。 [ メッセージ編集済み 編集者: Blue 編集日時 2007-01-22 17:53 ] | ||||||||||||||||||||||||||||
|
投稿日時: 2007-01-23 00:56
こんばんは。
C++には文法的な「インターフェイス」という概念はないのですが、 一般的には「純粋仮想関数のみをもつクラス」によって実現されます。
次にC++ではJavaやC#などと同じく、 インターフェイスや抽象クラスのインスタンスを作成することはできません。 ただし、C++とJava,C#の文法上の違いから この場合下記のように記述するとC++ではコンパイルエラーになります。 C++の場合、aは参照変数ではないからです。
参照やポインタであればエラーとはなりません。 # C++の参照はnullポインタをセットできないので、JavaやC#の参照とは少し違います。 C++のポインタであれば、nullポインタをセットすることができます。 C/C++の場合、ソースコードを後方参照することができないので、 使用する場合は、予めクラスを宣言するか定義する必要があります。 参照・ポインタのみであれば、宣言のみでコンパイルすることができます。
では最後に クラスAにクラスBへの関連を持たせるように、 クラスAを修正してみる場合、次の3通りができます。 パターン1
パターン2
パターン3
パターン1〜3は、寿命や多重度で使い分けをします。 | ||||||||||||||||||||||||||||
|
投稿日時: 2007-01-23 12:59
ざっとしか読んでないんだけど、たぶん「プロトタイプ宣言」について調べてみるといいんじゃないかな?
# VCだと、afx.hにプロトタイプ宣言書いておくようなスタイルじゃなかったっけ?(使った事無いからいい加減に言ってるけど。) | ||||||||||||||||||||||||||||
|
投稿日時: 2007-01-23 13:06
違いますね。afx.hはMFCのヘッダですので書き換えてはダメなのでは。 stdafx.h(プリコンパイル済みヘッダ)なら変更してもいいですけど。 まぁ、stdafx.hに全てのプロトタイプ宣言を書くことはないですけどね。 | ||||||||||||||||||||||||||||
|
投稿日時: 2007-01-23 13:29
こんにちは。
ちなみに
すでに回答が出ていますが、 このようなことはできません。 クラスAはクラスBを包含して、クラスBはクラスAを包含しているとすると、 クラスAのインスタンスのサイズは無限大になってしまいます。 AオブジェクトはBオブジェクトを持ち… そのBオブジェクトはAオブジェクトを持ち… そのAオブジェクトはBオブジェクトを持ち… そのBオブジェクトはAオブジェクトを持ち… (繰り返し) 巨大(無限大)なオブジェクトになってしまいます。 | ||||||||||||||||||||||||||||
|
投稿日時: 2007-01-23 14:21
試してみました。 なるほど〜、勉強になった。
このように書くと、A型のオブジェクトのメモリ領域にBの実体を含めるような動きをします。 C#をご存知のようですので、「Bを値型のように扱う」といえば分かるかな。 C#やJavaではB型オブジェクトへの参照を持つだけですので、動きは全然違くなりますね。 理解してわざと書いているならいいんですけど。 あと、タイトルの(CLI)ですけど、内容的にはCLIじゃないですよね。 CLIなら ref class A{ B^ b; } こうかな。 [ メッセージ編集済み 編集者: 一郎 編集日時 2007-01-23 14:23 ] | ||||||||||||||||||||||||||||
|
投稿日時: 2007-01-23 18:54
みなさん、アドバイスありがとうございました。
解決しました。 C++の経験は少しあったつもりでいたのですが、JavaやC#、VB.NETで慣れてしまった 状態でVC++(CLI)をやり始めたもので戸惑ってしまいました。 C++って、いろいろめんどくさいっすね。ヘッダとCPPファイルを分けたり。 でも、めんどくささに慣れればCLIはいろいろできるので面白くなってきましたけど。 |
1