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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14991497/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 18:52:19  来源:igfitidea点击:

C++ ERROR: forward declaration of 'struct...?

c++compiler-errorsincludecyclic-reference

提问by amorimluc

cyclical inclusion problem

循环包含问题

I forward declare one of the classes in the header of the other in an attempt to solve their cyclical inclusion. Here are my two files:

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

The first file (Parameter.h):

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

The second file (Expression.h):

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

As you can see, I forward declare Expression in Parameter.h, but I'm still getting the following two errors:

如您所见,我在 Parameter.h 中转发了声明表达式,但仍然出现以下两个错误:

forward declaration of 'struct Expression'

invalid use of incomplete type 'struct Expression'

“结构表达式”的前向声明

不完整类型“结构表达式”的无效使用

I looked a several previously posted questions but still, couldn't solve this problem. Thanks.

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

回答by juanchopanza

You can't forward declare Expressionbecause you need the full declaration for this:

你不能转发声明,Expression因为你需要完整的声明:

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

What you can do is move the implementation of the Parameter()constructor out of the header and into a .cppfile.

您可以做的是将Parameter()构造函数的实现从头.cpp文件中移到文件中。

回答by billz

You need to put Parameter constructor in a cpp file, when you call expr = new Expression();in constructor the Expression concrete type needs to be known.

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

Parameter.h

参数.h

#pragma once
#include "Token.h"

class Expression;

class Parameter {
public:

    Parameter();

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

Parameter.cpp

参数.cpp

#include "Parameter.h"

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

side note: could use smart pointers instead of raw pointers as class member? also variable name stringmay impact with std::string.

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

回答by qPCR4vir

Define the body of the constructor in a separate cpp file. The forward declaration of the class allow you to use pointers or references, bot not the constructor of the forward declared class, as you are using in the constructor of the "other" class. in a ccp file:

在单独的 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())
{    }

(now you are safe if new/constructors throw)

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