0

この質問は、次の重複と見なされるため終了します。

  1. C++ 循環ヘッダー依存関係
  2. ヘッダファイル間の循環依存
  3. C++ エラー: 'Line2' が宣言されていません

ただし、他の質問は私のものとは異なります。彼らは別のケースを尋ねており、答えは私の問題では機能しません。彼らの答えは、関数をファイルに入れ、.cpp宣言する前にクラスを定義することを提案しています。.cpp私のクラスはテンプレートであるため、関数を入れることができず、既にクラスを定義していますが、役に立ちません。


2 つのヘッダー ファイルa.hb.h. それらには、2 つのテンプレート クラスAとが定義されていBます。

A必要な機能は、オブジェクトのオブジェクトBと連携し、その逆も同様です。それらはテンプレートクラスなので、関数をファイルに入れることができず.cpp、ヘッダーにとどまらなければならず、インクルードの順序に大きな頭痛がします。

この問題を解決するための良い方法論は何ですか?

現在、関数定義を移動し、ヘッダーを正しい順序で含める方法を見つけていますが、これは常により複雑になります。さらに、関数定義がクラス宣言から離れているのは好きではありません (たとえば、他のファイル内)。


コード例:

ああ

#ifndef A_H
#define A_H

#include <iostream>
#include "b.h"
template< typename T > class B;

template< typename T >
class A {
public:
    B<void> *b;
    void f();
    void g();
};
template< typename T > void A<T>::f() {
    std::cout << "A::f" << std::endl;
    b->f();
}
template< typename T > void A<T>::g() {
    std::cout << "A::g" << std::endl;
}

#endif

bh

#ifndef B_H
#define B_H

#include <iostream>
#include "a.h"
template< typename T > class A;

template< typename T >
class B {
public:
    A<void> *a;
    void f();
    void g();
};
template< typename T > void B<T>::f( ) {
    std::cout << "B::f" << std::endl;
}
template< typename T > void B<T>::g( ) {
    std::cout << "B::g" << std::endl;
    a->g();
}

#endif

main.cpp

#include "a.h"
#include "b.h"
int main( ) {
    A<void> a;
    B<void> b;
    a.b = &b;
    b.a = &a;

    a.f();
    b.g();

    return 0;
}

a.hが含まれているため、これは機能しませんb.hb.hその場合は含めることができないため、エラーにa.hなりB::gます。

このサンプル コードでは、 のB::gmain.cppまたは最後に移動できますa.hが、より複雑なプログラムの場合、これは簡単ではありません。

4

1 に答える 1

1

実際、あなたのコードは私の Visual C++ でそのままコンパイルされます。main.cppその理由は、コンパイラが実際に呼び出されるまで、つまりあなたの場合まで、関数の「内部」を調べないためです。

率直に言って、これが標準で保証されているかどうかはわかりません。そうでない場合は、次のように、いつでもヘッダーを「独立」部分と「依存」部分に分割できます。

a_forward.h

#ifndef A_FORWARD_H
#define A_FORWARD_H

template< typename T > class B;

template< typename T >
class A {
public:
    B<T> *b;
    void f();
    void g();
};

#endif

ああ

#ifndef A_H
#define A_H

#include <iostream>
#include "a_forward.h"
#include "b_forward.h"

template< typename T > void A<T>::f() {
    std::cout << "A::f" << std::endl;
    b->f();
}

template< typename T > void A<T>::g() {
    std::cout << "A::g" << std::endl;
}

#endif

b_forward.h

#ifndef B_FORWARD_H
#define B_FORWARD_H

template< typename T > class A;

template< typename T >
class B {
public:
    A<T> *a;
    void f();
    void g();
};

#endif

bh

#ifndef B_H
#define B_H

#include <iostream>
#include "a_forward.h"
#include "b_forward.h"

template< typename T > void B<T>::f( ) {
    std::cout << "B::f" << std::endl;
}

template< typename T > void B<T>::g( ) {
    std::cout << "B::g" << std::endl;
    a->g();
}

#endif

main.cpp

---||---
于 2012-05-01T09:47:02.550 に答える