C ++错误:'struct ...的前向声明?

时间:2013-02-20 22:55:16

标签: c++ compiler-errors include cyclic-reference

周期性包含问题

我转发声明另一个标题中的一个类,试图解决它们的周期性包含。这是我的两个文件:

第一个文件( 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;
};

第二个文件( 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,但我仍然遇到以下两个错误:

  

'struct Expression'的前向声明

     

无效使用不完整类型'struct Expression'

我看了几个以前发过的问题,但仍然无法解决这个问题。感谢。

3 个答案:

答案 0 :(得分:9)

您无法转发声明Expression,因为您需要完整声明:

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

您可以做的是将Parameter()构造函数的实现移出标题并转移到.cpp文件中。

答案 1 :(得分:4)

您需要将参数构造函数放在cpp文件中,当您在构造函数中调用expr = new Expression();时,需要知道Expression具体类型。

Parameter.h

#pragma once
#include "Token.h"

class Expression;

class Parameter {
public:

    Parameter();

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

Parameter.cpp

#include "Parameter.h"

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

旁注:可以使用智能指针而不是原始指针作为类成员吗?变量名称string也可能会影响std::string

答案 2 :(得分: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())
{    }

(现在如果new / constructors抛出你就安全了)