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

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

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

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

Q&A

解決済

1回答

1885閲覧

複数クラスの循環参照

torimingo

総合スコア122

C++

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

0グッド

0クリップ

投稿2018/12/12 02:27

編集2018/12/12 02:51

C++で、3つのクラスが循環参照しているようで、コンパイルが通りません。
コードを以下に示します。
(クラス名が不自然ですが、問題の本質とは関連がないため、無視してください)

c++

1━━━━━ Actualクラス ━━━━━ 2 1 #ifndef ACTUAL 3 2 #define ACTUAL 4 3 5 4 #include "callback.h" 6 5 7 6 class Callback; 8 7 class Actual { 9 8 public: 10 9 int get() { 11 10 return 3; 12 11 } 13 12 Callback *callback; 14 13 }; 15 14 16 15 #endif 17 18━━━━━ Callbackクラス ━━━━━ 19 1 #ifndef CALLBACK 20 2 #define CALLBACK 21 3 22 4 #include "logic.h" 23 5 24 6 class Logic; 25 7 class Callback { 26 8 public: 27 9 void func() { 28 10 logic->print(); 29 11 } 30 12 Logic *logic; 31 13 }; 32 14 33 15 #endif 34 35━━━━━ Logicクラス ━━━━━ 36 1 #ifndef LOGIC 37 2 #define LOGIC 38 3 39 4 #include <iostream> 40 5 #include "actual.h" 41 6 using namespace std; 42 7 43 8 class Actual; 44 9 class Logic { 45 10 public: 46 11 void print() { 47 12 cout << actual->get() << endl; 48 13 } 49 14 Actual *actual; 50 15 }; 51 16 52 17 #endif 53 54━━━━━ Mainメソッド ━━━━━ 55 1 #include "actual.h" 56 2 #include "callback.h" 57 3 #include "logic.h" 58 4 59 5 int main() { 60 6 Actual actual; 61 7 Callback callback; 62 8 Logic logic; 63 9 64 10 actual.callback = &callback; 65 11 callback.logic = &logic; 66 12 logic.actual = &actual; 67 13 68 14 callback.func(); 69 15 return 0; 70 16 }

エラー出力を以下に示します。

In file included from callback.h:4:0, from actual.h:4, from main.cpp:1: logic.h: In member function ‘void Logic::print()’: logic.h:12:17: error: invalid use of incomplete type ‘class Actual’ cout << actual->get() << endl; ^~ logic.h:8:7: note: forward declaration of ‘class Actual’ class Actual;

解消方法をご存知の方がおりましたら、教えて頂けると幸いです。

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

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

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

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

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

y_waiwai

2018/12/12 02:34

エラーが出るならエラーメッセージをそのままの形で提示してください。 提示のソースでは、エラーは循環参照が原因ではないように思われますが
torimingo

2018/12/12 02:53

エラーメッセージを追記いたしましたので、ご確認のほど、お願い致します。
guest

回答1

0

ベストアンサー

1つの可能性として、#includeが循環しているためにエラーとなっていることが考えられます。

対策としては、

  • (コンパイラが対応していれば)#pragma onceを入れる
  • ヘッダファイル全体を#ifndef ... #endifで覆うインクルードガードを行う

のどちらかとなります。

投稿2018/12/12 02:38

編集2018/12/12 02:39
maisumakun

総合スコア145184

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

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

torimingo

2018/12/12 02:54

ヘッダファイルをインクルードガードで覆っても、コンパイルが通りませんでした。 (エラーメッセージを追記しましたので、お時間がございましたらご確認のほどお願い致します)
maisumakun

2018/12/12 03:18

メソッドでactual->getやactual->getのように呼ぶには、その時点で不完全型であってはいけません。 メソッドをヘッダに書くと定義順の問題ですべて完全型にするのが難しいので、「.cppでメソッドを定義する」ことが必要かもしれません。 もしくは、Actualの宣言ではCallbackは不完全型のままで構わないので、actual.hがcallback.hを#includeするのをやめる、でも解決するかもしれません。
torimingo

2018/12/12 03:54

actual.hがcallback.hを#includeするのをやめたら解決しました。 (なぜ、Actualの宣言ではCallbackは不完全型のままでよいのでしょうか・・) 早急なご回答をありがとうございました。
maisumakun

2018/12/12 03:58

Actualの中では不完全型のポインタを宣言しているだけなので、不完全型のままでも処理可能です。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問