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

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

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

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

Q&A

解決済

2回答

17215閲覧

C++のクラスの前方宣言の仕方がよくわからないです。

buuuu14

総合スコア15

C++

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

0グッド

0クリップ

投稿2017/09/28 13:42

こんな感じのコードを動かしたいのですが、クラスBの定義が不完全みたいなエラーが出ます

main.cpp

1#include <iostream> 2using namespace std; 3 4// クラスBの前方宣言 5class B; 6 7// クラスAの定義 8class A { 9private: 10 B *b; 11 12public: 13 void run1() { 14 b->run2(); 15 } 16 void run3() { 17 cout << "finish" << endl; 18 } 19}; 20 21// クラスBの定義 22class B { 23private: 24 A *a; 25public: 26 void run2() { 27 a->run3(); 28 } 29}; 30 31// メイン関数 32int main(void) { 33 A a; 34 a.run1(); 35} 36

ここで実行してみてください。
https://paiza.io/ja/projects/new

要するにクラスの相互参照をしたいのですが、うまくいきません。
どうすればよいでしょうか?
ご教授のほどよろしくお願いします。

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

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

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

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

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

guest

回答2

0

ベストアンサー

これならいけますよ。

C++

1#include <iostream> 2using namespace std; 3 4// クラスBの前方宣言 5class B; 6 7// クラスAの定義 8class A { 9private: 10 B *b; 11 12public: 13 void run1(); 14 void run3() { 15 cout << "finish" << endl; 16 } 17}; 18 19// クラスBの定義 20class B { 21private: 22 A *a; 23public: 24 void run2() { 25 a->run3(); 26 } 27}; 28 29void A::run1() { 30 b->run2(); 31} 32 33// メイン関数 34int main(void) { 35 A a; 36 a.run1(); 37}

クラスを前方宣言することで**『クラスである』という情報を前もって与えられます。
逆に言うと、
『クラスである』**という情報を過ぎる次の操作は出来ません。

  • 実体の宣言
  • メンバ変数の参照
  • メンバ関数の参照/呼び出し

実際に組むときは、クラス宣言と実装を分離することで回避できます。

C++

1/* A.hpp */ 2// クラスBの前方宣言 3class B; 4 5// クラスAの定義 6class A { 7private: 8 B *b; 9 10public: 11 void run1(); 12 void run3(); 13};

C++

1/* A.cpp */ 2#include "A.hpp" 3#include <iostream> 4 5void A::run1() { 6 b->run2(); 7} 8void A::run3() { 9 std::cout << "finished" << std::endl; 10}

C++

1/* B.hpp */ 2class A; 3 4class B { 5private: 6 A *a; 7public: 8 void run2(); 9};

C++

1/* B.cpp */ 2#include "B.hpp" 3 4void B::run2() { 5 a->run3(); 6}

ついでにusing namespace std;を排除しました。
使い方を間違えると、名前空間の利益をぶっ壊すので...

投稿2017/09/28 13:47

編集2017/09/28 13:55
LouiS0616

総合スコア35658

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

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

buuuu14

2017/09/28 14:00 編集

やっと理解できました。 迅速な回答ありがとうございます。 前方宣言は処理を保留してくれるものだと思ってました( ´_`;;;)
guest

0

不完全型のままではメソッドを呼ぶことができませんので、クラス内ではメソッドの宣言だけにしておいて、classAclass Bとも宣言が出揃ったところで、メソッドの実装を行ってください。

ただし、それとは別問題で、AやBのインスタンスをコンストラクタなどで用意しないと、不正ポインタ参照でおかしくなります。

投稿2017/09/28 13:50

maisumakun

総合スコア145121

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

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

buuuu14

2017/09/28 14:02

回答ありがとうございます。 やっと理解することができました。 (すいませんnewを忘れていました( ´_`;;;))
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問