C ++ ОШИБКА: предварительное объявление ‘struct …?

проблема циклического включения

Я жду объявления одного из классов в заголовке другого в попытке решить их циклическое включение. Вот мои два файла:

Первый файл (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;
};

Как видите, я пересылаю объявление Expression в Parameter.h, но я по-прежнему получаю следующие две ошибки:

предварительное объявление ‘struct Expression’

недопустимое использование неполного типа ‘выражение структуры’

Я просмотрел несколько ранее опубликованных вопросов, но все же не смог решить эту проблему. Благодарю.

4

Решение

Вы не можете переслать объявить Expression потому что вам нужна полная декларация для этого:

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

Что вы можете сделать, это переместить реализацию Parameter() Конструктор из заголовка и в .cpp файл.

9

Другие решения

Вам нужно поместить конструктор параметров в файл 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,

4

Определите тело конструктора в отдельном файле 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())
{    }

(теперь вы в безопасности, если новые / конструкторы бросают)

2
По вопросам рекламы [email protected]