2

このコードはコンパイルされていません。

望ましい結果を得るためにどのような変更を加えることができますか?

ClassOne.h

#ifndef _CLASS_ONE_
#define _CLASS_ONE_

#include <string>
#include "ClassTwo.h"

class ClassTwo;

class ClassOne
{
private:
    string message;     
    friend ClassTwo;
    ClassTwo m_ClassTwo;

public:
    ClassOne();
    void Display();
};

#endif

ClassTwo.h

#ifndef _CLASS_TWO_
#define _CLASS_TWO_

#include <string>
#include "ClassOne.h"

class ClassOne;

class ClassTwo
{
private:
    string message;
    friend ClassOne;
    ClassOne m_ClassOne;

public:
    ClassTwo();
    void Display();
};

#endif

ClassOne.cpp

#include "ClassOne.h"
#include "ClassTwo.h"
#include <iostream>

ClassOne :: ClassOne()
{
    std::cout<<"ClassOne()...called\n";
    this->m_ClassTwo.message = "ClassOne - Message\n";
}

void ClassOne :: Display()
{
    std::cout<<this->m_ClassTwo.message;
}

ClassTwo.cpp

#include "ClassTwo.h"
#include "ClassOne.h"
#include <iostream>

ClassTwo :: ClassTwo()
{
    std::cout<<"ClassTwo()...called\n";
    this->m_ClassOne.message = "ClassTwo - Message\n";
}

void ClassTwo :: Display()
{
    std::cout<<this->m_ClassOne.message;
}

main.cpp

#include "ClassOne.h"
#include "ClassTwo.h"

int main()
{
    ClassOne one;
    one.Display();

    ClassTwo two;
    two.Display();
}

エラーメッセージ

1   error C2146: syntax error : missing ';' before identifier 'message'
2   error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
3   error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
4   error C2079: 'ClassTwo::m_ClassOne' uses undefined class 'ClassOne'
5   error C2146: syntax error : missing ';' before identifier 'message'
6   error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
7   error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
8   error C2039: 'message' : is not a member of 'ClassTwo'
9   error C2039: 'message' : is not a member of 'ClassTwo'
10  error C2146: syntax error : missing ';' before identifier 'message'
11  error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
12  error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
13  error C2079: 'ClassOne::m_ClassTwo' uses undefined class 'ClassTwo'
14  error C2146: syntax error : missing ';' before identifier 'message'
15  error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
16  error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
17  error C2039: 'message' : is not a member of 'ClassOne'
18  error C2039: 'message' : is not a member of 'ClassOne'
19  error C2146: syntax error : missing ';' before identifier 'message'
20  error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
21  error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
22  error C2079: 'ClassTwo::m_ClassOne' uses undefined class 'ClassOne'
23  error C2146: syntax error : missing ';' before identifier 'message'
24  error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
25  error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
4

3 に答える 3

6

そのコードをコンパイルすることはできません。タイプ A がタイプ B を含み、タイプ B がタイプ A を含むシステムを説明しました。したがって、タイプ A とタイプ B の両方が再帰的かつ無限にそれ自体を含みますが、これは不可能です。この問題を解消するには、コードを根本的に再構築する必要があります。

また、friend構文が間違っています。

于 2012-02-27T07:51:53.467 に答える
3

前述のように、ClassOneまたはClassTwoの少なくとも1つを前方宣言する必要があります。

そのため、ClassOne.hは次のようになります。

#ifndef _CLASS_ONE_
#define _CLASS_ONE_

#include <string>

class ClassTwo;

class ClassOne
{
private:
    string message;
    ClassTwo* m_ClassTwo;

public:
    ClassOne();
    void Display();
};

#endif

ご覧のとおり、ClassTwoを宣言していますが、これは含めていません。基本的には、ClassTwoがあることをコンパイラに伝えるだけですが、現時点では、ClassTwoに何が含まれているのかは気にしません。

ClassTwoメンバーも見てください。これがポインターになりました。その理由は、メンバーがコンパイラーにオブジェクトのサイズを知っていることを要求するためです。これは現在、何であるかがわかりません。そのため、ポインタまたは参照のいずれかが必要です。

次に、ClassOne.cppに、そのクラスの関数とサイズを取得するためにClassTwo.hを含める必要があります。

ただし、いくつかの点があります。ClassTwoから継承できない前方宣言では、ヘッダーファイルで転送されたクラスのメソッドを使用します(コンパイラはどのメソッドが存在するかをどのように認識しますか?)転送されたクラスを使用して関数またはメソッドを定義します。参照を渡すか、ポインターを渡す必要があります。

于 2012-02-27T08:07:10.930 に答える
1

1) 前方宣言を使用します。

追加

class ClassTwo;

ClassOne.hへ

class ClassTwo;

ClassTwo.h へ

2) メンバー変数 (または少なくとも 1 つ) を動的に作成する必要があります。演算子 new を使用するか、または必要に応じてスマート ポインターの 1 つを使用します ( C++ を使用する場合はboost::shared_ptrブースト ライブラリまたは標準ライブラリから)。 std::shared_ptr11.

于 2012-02-27T07:58:42.703 に答える