[解決済み] C++で "X does not name a type "エラー
質問
以下のような2つのクラスが宣言されています。
class User
{
public:
MyMessageBox dataMsgBox;
};
class MyMessageBox
{
public:
void sendMessage(Message *msg, User *recvr);
Message receiveMessage();
vector<Message> *dataMessageList;
};
gccでコンパイルしようとすると、以下のようなエラーが出ます。
MyMessageBoxに型名がありません。
解決方法は?
コンパイラがクラスをコンパイルするとき
User
を取得し
MyMessageBox
の行になります。
MyMessageBox
はまだ定義されていません。コンパイラは
MyMessageBox
が存在するため、クラスのメンバの意味を理解できません。
を確認する必要があります。
MyMessageBox
が定義されている
前に
をメンバーとして使用する場合。これは、定義順を逆にすることで解決します。しかし、循環的な依存関係があります。
MyMessageBox
上記
User
の定義では
MyMessageBox
という名前は
User
は定義されません!
できることは
前方宣言
User
つまり、宣言はするが、定義はしない。コンパイル時に、宣言されているが定義されていない型は
未完成型
.
もっと簡単な例で考えてみましょう。
struct foo; // foo is *declared* to be a struct, but that struct is not yet defined
struct bar
{
// this is okay, it's just a pointer;
// we can point to something without knowing how that something is defined
foo* fp;
// likewise, we can form a reference to it
void some_func(foo& fr);
// but this would be an error, as before, because it requires a definition
/* foo fooMember; */
};
struct foo // okay, now define foo!
{
int fooInt;
double fooDouble;
};
void bar::some_func(foo& fr)
{
// now that foo is defined, we can read that reference:
fr.fooInt = 111605;
fr.foDouble = 123.456;
}
を前方に宣言することで
User
,
MyMessageBox
は、まだそれへのポインタや参照を形成することができます。
class User; // let the compiler know such a class will be defined
class MyMessageBox
{
public:
// this is ok, no definitions needed yet for User (or Message)
void sendMessage(Message *msg, User *recvr);
Message receiveMessage();
vector<Message>* dataMessageList;
};
class User
{
public:
// also ok, since it's now defined
MyMessageBox dataMsgBox;
};
あなた
できない
前述のように、クラスのメンバには定義が必要です。(その理由は、コンパイラがどの程度のメモリ
User
が占有し、それを知るためには、そのメンバーのサイズを知る必要がある)。もし、あなたが
class MyMessageBox;
class User
{
public:
// size not available! it's an incomplete type
MyMessageBox dataMsgBox;
};
まだサイズを知らないので、うまくいかないでしょう。
余談ですが、この機能。
void sendMessage(Message *msg, User *recvr);
おそらく、どちらもポインタで取ってはいけないのでしょう。メッセージなしでメッセージを送信することはできませんし、送信先のユーザーなしでメッセージを送信することもできません。そして、この2つの状況は、どちらかのパラメータの引数にnullを渡すことで表現できます(nullは完全に有効なポインタ値です!)。
そうではなく、参照(場合によってはconst)を使用します。
void sendMessage(const Message& msg, User& recvr);
関連
-
[解決済み】C++の余分な資格エラー
-
[解決済み] explicit キーワードの意味は?
-
[解決済み] C++11では、標準化されたメモリモデルが導入されました。その意味するところは?そして、C++プログラミングにどのような影響を与えるのでしょうか?
-
[解決済み] オブジェクトの種類を決定しますか?
-
[解決済み] 型チェック:typeof、GetType、is?
-
[解決済み] Pythonで型をチェックする標準的な方法は何ですか?
-
[解決済み] 型名の後の括弧は、newで違いがあるのでしょうか?
-
[解決済み】type()とisinstance()の違いは何ですか?)
-
[解決済み】pandasでカラムの種類を変更する
-
[解決済み】TypeScriptのコールバックタイプの定義
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] エラーが発生する。ISO C++は型を持たない宣言を禁じています。
-
[解決済み] [Solved] Error C1083: Cannot open include file: 'stdafx.h'
-
[解決済み】'cout'は型名ではない
-
[解決済み] 非常に基本的なC++プログラムの問題 - バイナリ式への無効なオペランド
-
[解決済み] 既に.objで定義されている-二重包含はない
-
[解決済み】リンカーエラーです。"リンカ入力ファイルはリンクが行われていないため未使用"、そのファイル内の関数への未定義参照
-
[解決済み] 非静的データメンバの無効な使用
-
[解決済み】なぜ、サイズ8の初期化されていない値を使用するのでしょうか?
-
[解決済み】警告 - 符号付き整数式と符号なし整数式の比較
-
[解決済み] c++で構造体が型名にならない