4

循環的包含問題

循環的な包含を解決するために、クラスの 1 つを他のクラスのヘッダーで前方宣言します。ここに私の2つのファイルがあります:

最初のファイル ( Parameter.h ):

#pragma once
#include "Token.h"`

class Expression;

class Parameter {
public:

    Parameter() {
        string = new Token();
        identifier = new Token();
        expr = new Expression();
    }

    Token* string;
    Token* identifier;
    Expression* expr;
};

2 番目のファイル ( Expression.h ):

#pragma once
#include "Token.h"
#include "Parameter.h"

class Expression {
public:
    Expression() {
        param1 = new Parameter();
        param2 = new Parameter();
        op = new Token();
    }

    Expression(Parameter* p1, Token* o, Parameter* p2) {
        param1 = p1;
        param2 = p2;
        op = o;
    }

    Parameter* param1;
    Parameter* param2;
    Token* op;
};

ご覧のとおり、Parameter.h で Expression を前方宣言していますが、まだ次の 2 つのエラーが発生しています。

「構造式」の前方宣言

不完全なタイプ 'struct Expression' の無効な使用

以前に投稿されたいくつかの質問を見ましたが、それでもこの問題を解決できませんでした。ありがとう。

4

3 に答える 3

9

Expressionこれには完全な宣言が必要なため、前方宣言はできません。

Parameter() {
    string = new Token();
    identifier = new Token();
    expr = new Expression();  // here!
}

できることは、Parameter()コンストラクターの実装をヘッダーから.cppファイルに移動することです。

于 2013-02-20T22:57:13.030 に答える
4

コンストラクターを呼び出すときは、パラメーター コンストラクターを cpp ファイルに配置する必要がありますexpr = new Expression();。式の具象型を知る必要があります。

パラメータ.h

#pragma once
#include "Token.h"

class Expression;

class Parameter {
public:

    Parameter();

    Token* token;
    Token* identifier;
    Expression* expr;
};

パラメータ.cpp

#include "Parameter.h"

Parameter::Parameter()
: token(new Token()),
  identifier(new Token()),
  expr(new Expression())
{
}

補足:クラスメンバーとして生のポインターの代わりにスマートポインターを使用できますか? また、変数名stringは に影響を与える可能性がありますstd::string

于 2013-02-20T22:57:21.563 に答える
2

別の cpp ファイルでコンストラクターの本体を定義します。クラスの前方宣言により、「他の」クラスのコンストラクターで使用しているように、前方宣言されたクラスのコンストラクターではなく、ポインターまたは参照を使用できます。ccp ファイルで:

#include "Parameter.h"
#include "Expression.h"   //   ??

Parameter::Parameter():   string (new Token()),
                          identifier(new Token()),
                          expr ( new Expression())
{}


Expression::Expression() param1 (new Parameter()),
                         param2 (new Parameter()),
                         op ( new Token())
{    }

(新しい/コンストラクターがスローしても安全です)

于 2013-02-20T22:58:12.437 に答える