Frage

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):

#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):

#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:

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.

War es hilfreich?

Lösung

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

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 .cpp file.

Andere Tipps

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.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())
{
}

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

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:

#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)

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top