简体   繁体   中英

Issue with C++ or Visual Studio 2010

I'm picking up C++ again after a while, and I'm having trouble understanding a certain behavior. I don't know if it's a fault in VS 2010, or just C++. I'm working on a school project, so forgive the "hokey-ness" of the program. First, I'll just post the relevant files and their contents:
BarFly.h:

#ifndef PJ_BARFLY_H
#define PJ_BARFLY_H

#include "BarFlyOwnedStates.h"
#include "BaseGameEntity.h"
#include "FSM\StateMachine.h"

class BarFly : public BaseGameEntity {

private:
  StateMachine<BarFly>* state_machine;

public:

  BarFly(int id);

};

#endif // PJ_BARFLY_H

BarFlyOwnedStates.h:

#ifndef PJ_BARFLYOWNEDSTATES_H
#define PJ_BARFLYOWNEDSTATES_H

#include "BarFly.h"
#include "FSM/State.h"

class BarFly; // << Line A <<

class CarousingState : public State<BarFly>
{

public:

  static CarousingState *Instance();

  // Some non-relevant functions

};

#endif // PJ_BARFLYOWNEDSTATES_H

BarFly.cpp:

#include "BarFly.h"


BarFly::BarFly(int id) : BaseGameEntity(id) {
  state_machine = new StateMachine<BarFly>(this);
  state_machine->SetCurrentState(CarousingState::Instance()); // << Line B <<
}

Alright, so my question is, why do I need to include Line A? When I leave that out, VS complains about Line B, saying that it doesn't recognize CarousingState* as a State <BarFly> *. Any feedback is appreciated.

You have two header files that include each other. That doesn't work.

Your include guard will hide the class in the second file. That's why you need line A. If that's enough to compile the code, just remove the include at the top of that header.

The cpp file, on the other hand, should include all the headers it uses.

The problem is that you have a circular header dependency; "BarFly.h" and "BarFlyOwnedStates.h" each try to include each other. The result is that, when you include "BarFly.h" , the include guards mean that the definition of BarFly comes after that of CarousingState , so BarFly has not been declared at the point it's used as a template argument.

Line A is a "forward declaration" (or just "declaration"); it declares that the class exists, but does not define the class. Until the class is defined, it's known as an "incomplete type", and can be used in some situations.

In general, you should avoid circular dependencies like this, as they can cause much confusion. Include a header only when you actually need to, and just use forward declarations of classes whenever you can.

In this case, it looks like you can remove #include "BarFlyOwnedStates.h" from BarFly.h , and depending on what State does with its template argument, you might also be able to remove #include "BarFly.h" from BarFlyOwnedStates.h (keeping the forward declaration on Line A). You will need to include both headers from the source file.

This probably has to do with the circular dependency you've set up between BarFly and BarFlyOwnedStates. Try placing the #include "BarFly.h" in BarFlyOwnedStates.cpp instead of in the header.

It's called a forward declaration. Line A tells the compiler parsing BarFlyOwnedStates.h: not to worry there will be a class called BarFLy which you promise to define latter.

Otherwise BarFlyOwnedStates.h: would have to include barfly.h, which would introduce a circular dependancy.

ps do you need #include "BarFlyOwnedStates.h" and #include "BaseGameEntity.h" to be included in BarFly.h? It's best to use the class forward declaration to minimise including headers in other headers

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM