-3

Im a fairly new programmer so I may not be understanding typedef correctly.

I have 2 classes Enemy.cpp and AI.cpp. My AI.cpp needs values from Enemy.cpp to be able to process its movements etc. In AI.cpp I hold pointers to values such as position, speed and an enum for the direction the enemy is facing.

The Errors I get are listed below. If there is a more simple way to link an enum variable between classes, im all ears.

below is a working example of the error.

///////MAIN.H/////////////

#ifndef  _MAIN_H_
#define _MAIN_H_



#endif // ! _MAIN_H_

///////////////////////////

////////MAIN.CPP///////////

#include "AI.h"
#include "Enemy.h"

int main(int argc, char* args[])
{
    Enemy enemy; 

}

//////////////////////////////

//////////ENEMY.H///////////////

#ifndef _ENEMY_H_
#define _ENEMY_H_ 

#include "AI.h"

class Enemy 
{

public: 

    Enemy();

    enum Facing
    {
        LEFT = 0,
        RIGHT
    };



protected:

    AI* EnemiesAI; 
    //try this as a pointer
    Facing EnemyDirection;

};


#endif

//////////////////////////////////

///////////ENEMY.CPP////////////////

#include "Enemy.h"

Enemy::Enemy()
{
    EnemiesAI = new AI; 

    EnemiesAI->LinkEnemyToAI(&EnemyDirection);
}

////////////////////////////////////

/////////////////AI.H//////////////

#ifndef _AI_H_
#define _AI_H_

#include "Enemy.h"

class AI
{
public: 

    /*this needs to be a pointer, otherwise I have to pass the 
    value into AI on every update*/
    typedef Enemy::Facing *ThisFacing; //Error 3

    void LinkEnemyToAI(ThisFacing facing);

private: 
    //This is a pointer to a Enemy::Facing object
    ThisFacing mFacing; 


};

#endif

///////////////////////////////////////

////////////////AI.CPP/////////////////

#include "AI.h"

void AI::LinkEnemyToAI(ThisFacing facing)
{
    mFacing = facing;
}

////////////////////////////////////////

Error C2653 'Enemy': is not a class or namespace name ExampleOfTypeDefError c:\dev\projects\exampleoftypedeferror\exampleoftypedeferror\ai.h 11

Severity Code Description Project File Line Error C4430 missing type specifier - int assumed. Note: C++ does not support default-int ExampleOfTypeDefError c:\dev\projects\exampleoftypedeferror\exampleoftypedeferror\ai.h 11

Severity Code Description Project File Line Error C3646 'mFacing': unknown override specifier ExampleOfTypeDefError c:\dev\projects\exampleoftypedeferror\exampleoftypedeferror\ai.h 17

Severity Code Description Project File Line Error C4430 missing type specifier - int assumed. Note: C++ does not support default-int ExampleOfTypeDefError c:\dev\projects\exampleoftypedeferror\exampleoftypedeferror\ai.h 17

Severity Code Description Project File Line Error C2660 'AI::LinkEnemyToAI': function does not take 1 arguments ExampleOfTypeDefError c:\dev\projects\exampleoftypedeferror\exampleoftypedeferror\enemy.cpp 7

Severity Code Description Project File Line Error C2061 syntax error: identifier 'ThisFacing' ExampleOfTypeDefError c:\dev\projects\exampleoftypedeferror\exampleoftypedeferror\ai.h 13

Severity Code Description Project File Line Error C2238 unexpected token(s) preceding ';' ExampleOfTypeDefError c:\dev\projects\exampleoftypedeferror\exampleoftypedeferror\enemy.h 23

Dan Jones
  • 3
  • 3
  • 2
    Would you mind posting a [Minimal, Complete, and Verifiable example](http://stackoverflow.com/help/mcve)? Your posted code doesn't seem compilable because there are `public:` and `Protected:` in storange positions. – MikeCAT Aug 14 '17 at 12:32
  • 2
    You have `Protected:` and `Private:` in your code. Are you programming on a phone with autocorrect? – LogicStuff Aug 14 '17 at 12:32
  • 2
    you cant include AI.h in Enemy.h and Enemy.h in AI.h at the same time. Rethink your design (imho circular dependencies are always bad) or use a forward declaration – 463035818_is_not_an_ai Aug 14 '17 at 12:32
  • 1
    Besides the [Minimal, Complete, and Verifiable Example](http://stackoverflow.com/help/mcve), please copy-paste the actual error messages (complete, in full, with possible informational notes, and without modifications) into your question. – Some programmer dude Aug 14 '17 at 12:34
  • 1
    `Enemy::Facing *` (a.k.a. `ThisFacing`) is not the same type as `Enemy::Facing`. `&` means different things in types and in expressions. Review the chapters on pointers and references in your favourite C++ book. – molbdnilo Aug 14 '17 at 13:11
  • edits made @tobi303 I understand circular dependencies and it is on my list of things to do. As you can see though I use #ifndef to avoid serious problems for now. – Dan Jones Aug 14 '17 at 18:04
  • edits made @someprogrammerdude – Dan Jones Aug 15 '17 at 13:01

1 Answers1

0

Using include-guards here doesn't help really, because Enemy.h depends on AI.h which depends on Enemy.h and so on forever.

You have to break that chain, and the easiest way to break it is through something called forward declarations.

If you look closer in the Enemy.h header file, all it uses of the AI class is to declare a member variable which is a pointer to AI. That means you don't need the full definition of AI, you only need to tell the compiler that the class AI exists. Something like

#ifndef ENEMY_H
#define ENEMY_H

class AI;  // Forward declaration of the AI class    

class Enemy 
{
public: 
    Enemy();

    enum Facing
    {
        LEFT = 0,
        RIGHT
    };

protected:
    AI* EnemiesAI; 
    //try this as a pointer
    Facing EnemyDirection;
};

#endif // ENEMY_H

Now in the Enemy.cpp file you still need to #include "AI.h" since the full definition of the class is needed there.

This forward declaration isn't really possible in the AI.h header file, since in it you use the enumeration Enemy::Facing. However, since Enemy.h no longer includes AI.h there's no longer the circular dependency.

Also note that I changed the header guard macro to not have leading underscores, since all symbols with a leading underscore follower by an upper-case letter is reserved in all scopes. See e.g. this question and its answers for more details.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • Thanks, @someprogrammerdude. Does that actually resolve the errors that Im getting in the example code? you havent specified that it does. My code does compile so I do not believe that this is the main issue here. – Dan Jones Aug 15 '17 at 14:02
  • @DanJones Yes it will solve some of the errors you list. And yes I said what it does, it exchanges the `#include "AI.h"` to `class AI;`, i.e. it makes a forward declaration of the `AI` class instead of including the AI.h` header file. – Some programmer dude Aug 15 '17 at 14:05
  • Thanks, thats done it. I had some other issues with other classes which i had to resolve aswell. But my code is now compiling correctly. I will have to be more aware of circular dependencies in the future. @someprogrammerdude – Dan Jones Aug 16 '17 at 12:13