Resolving a circular reference in c++ header files [duplicate] - c++

This question already has an answer here:
C++ Circular Dependency in Header Files
(1 answer)
Closed 6 years ago.
I am encountering a circular include reference error where I wish to use an object of type Deck in CardFactory, and an object of type CardFactory in Deck. Any hints as to how to fix this problem?
//CardFactory.h
#ifndef CARDFACTORY_H
#define CARDFACTORY_H
#include "Deck.h"
#include <string>
using std::string;
class CardFactory {
public:
Deck getDeck();
static CardFactory* getFactory() {
static CardFactory singleton;
return &singleton;
}
};
#endif
//Deck.h
#ifndef DECK_H
#define DECK_H
#include <vector>
#include <iostream>
#include "CardFactory.h"
using std::ostream;
class Deck : public std::vector<Card*> {
friend ostream& operator<<(ostream& os, const Deck& dt);
Card* draw();
Deck(CardFactory* cf);
};
#endif

Forward reference (or forward declaration).
In Deck.h you don't need to #include "CardFactory.h", instead just declare the class.
class CardFactory;
This should work because in Deck class you are only using pointer to class CardFactory

Related

C++ Why Is There "Unknown Type" When Class Header is Included? [duplicate]

This question already has answers here:
Resolve build errors due to circular dependency amongst classes
(12 answers)
Closed 6 years ago.
I have this header file and I'm trying to make variables of type Item. I've included #include "Item.h" and yet I still get a unknown type name Item error on both private variables when I compile.
#ifndef PLAYER_H
#define PLAYER_H
#include <vector>
#include "Item.h"
using std::vector;
class Player
{
public:
// constructor
Player( void );
// destructor
virtual ~Player( void );
private:
Item item;
std::vector <Item> inventory;
};
#endif /* PLAYER_H */
Whats up with this?
Heres the Item.h that I'm including
#ifndef ITEM_H
#define ITEM_H
#include <string>
#include "Player.h"
#include "GlobalDefs.h"
class Item {
public:
Item();
Item(gold_t v, std::string n);
virtual ~Item();
// Getter
inline virtual gold_t GetValue (void)
{
return value;
}
// Getter
inline virtual std::string GetName (void);
// Getter
virtual std::string GetItemText(void);
protected:
gold_t value;
std::string name;
};
#endif /* ITEM_H */
If you include Item.h from your cpp file, Player.h is included from it. Then, Player.h includes Item.h again, but thanks to the include guard, this does virtually nothing.
Then, in the included Player.h, no Item is declared yet. Therefore, the compiler will emit the error.
Since nothing from Player.h is used in Item.h, remove #include "Player.h" from Item.h.
You're including "Player.h" in "Item.h" and make it circular dependency. Since it's not necessary at all so just remove it.

C++ undefined reference to vtable on compile [duplicate]

This question already has answers here:
Undefined reference to vtable
(21 answers)
Closed 9 years ago.
Why do I keep getting an error on compile with this code?
#ifndef OPERATOR_H
#define OPERATOR_H
#include <cstdlib>
#include <iostream>
#include <string>
#include "Individual.h"
using namespace std;
class Operator
{
public:
Operator();
virtual void execute (Individual* parent);
private:
};
#endif
Then in the cpp file I have
#include <cstdlib>
#include <iostream>
#include <string>
#include "Operator.h"
using namespace std;
Operator::Operator()
{
}
void execute(Individual* parent)
{
}
Define a destructor. The vtable for a class with virtual methods is created in the translation unit that defines the constructor.
In your header, add:
virtual ~Operator();
And in your source file, add:
Operator::~Operator() {
}

Undeclared Identifier vector of pointers to objects

Error: Line 12 of Cell.h: 'Actor' undeclared identifier.
If I try to forward declare above it, it says that there's a redefinition. What do I do?
Actor.h:
#ifndef ACTOR_H
#define ACTOR_H
#include <iostream>
#include <vector>
#include <string>
#include "Cell.h"
using namespace std;
class Actor //Simple class as a test dummy.
{
public:
Actor();
~Actor();
};
#endif
Cell.h:
#include <iostream>
#include <string>
#include <vector>
#include "Actor.h"
#ifndef CELL_H
#define CELL_H
using namespace std;
class Cell // Object to hold Actors.
{
private:
vector <Actor*> test;
public:
Cell();
~Cell();
vector <Actor*> getTest();
void setTest(Actor*);
};
#endif
Cell.cpp:
#include "Cell.h"
#include <vector>
vector<Actor*> Cell::getTest() //These functions also at one point stated that
{ // they were incompatible with the prototype, even
} // when they matched perfectly.
void Cell::setTest(Actor*)
{
}
What else can I do?
Remove the #include "Cell.h" from Actor.h and you're set to go.
In general, prefer forward declarations where you can, and includes where you must. I'd also replace the #include "Actor.h" from Cell.h with a forward declaration: class Actor;.
In the cpp files you can include the headers if you need them.
You have recursive #includes via your mutual references between cell.h and actor.h.
In Cell.h, delete #include <Actor.h>.
In Cell.h, add the line class Actor; just above the definition of class Cell.
In Cell.cpp, you might need to add #include "Actor.h".

Namespace problems

So I am getting the following errors:
..\Actor.h:35: error: `Attack' is not a member of `RadiantFlux'
..\Actor.h:35: error: template argument 1 is invalid
..\Actor.h:35: error: template argument 2 is invalid
..\Actor.h:35: error: ISO C++ forbids declaration of `attacks' with no type
On this line (among others):
std::vector<RadiantFlux::Attack> attacks;
Here are the relevant files:
Actor.h:
#ifndef ACTOR_H_
#define ACTOR_H_
#include <string>
#include <vector>
#include "Attack.h"
namespace RadiantFlux {
...
class Actor {
private:
std::string name;
int health;
std::vector<RadiantFlux::Attack> attacks;
Attributes attributes;
public:
...
};
}
#endif /* ACTOR_H_ */
Attack.h:
#ifndef ATTACK_H_
#define ATTACK_H_
#include <string>
#include <stdlib.h>
#include <time.h>
#include "Actor.h"
namespace RadiantFlux {
...
class Attack {
private:
...
public:
...
};
}
#endif /* ATTACK_H_ */
Why am I getting these errors and what can I do to fix them? I am assuming it has something to do with the namespaces...
You have a cyclic dependency of your header files.
Attack.h includes Actor.h and vice versa.
Use Forward Declaration of class to avoid circular dependency problems.
Since the OP's comments, here is what needs to be done:
class Actor;
class Attack
{
};
If your code fails to compile after doing this, You need to read the linked answer and Understand why the error and how to solve it. The linked answer explains it all.
The classes Actor and Attack both refer to each other, so you will need to add a forward declaration in one of the file.
For example, in Actor.h:
class Attack;
class Actor
{
...
};

inheritance error: "expected class-name before '{' token"

I am writing a poker program, where two classes I have are a Deck class and a Hand class. The Hand class inherits from the Deck class, so it can use its printGroup method. However, when I compile I get an error that says:
expected class-name before '{' token
referring to the line:
class Hand : public Deck{
Here is the code for the two class headers. Could anyone help me solve this?
//Hand header
#ifndef HAND_H
#define HAND_H
#include <iostream>
#include <vector>
#include "Deck.h"
#include "Card.h"
class Card;
class Hand : public Deck{ //error occurs from this line
public:
Hand(){}
void createHand(std::vector<Card> &, std::vector<Card> &);
};
#endif /* HAND_H */
//Deck header
#ifndef DECK_H
#define DECK_H
#include <iostream>
#include <vector>
#include "Card.h"
class Card;
class Deck{
public:
Deck(){}
void createDeck(std::vector<Card> &);
void printGroup(std::vector<Card> &, int);
void sortDeck(std::vector<Card> &, int, int);
};
#endif /* DECK_H */
Assuming that #marcog's gut feeling that it is a circular dependency is correct (maybe Card.h includes Hand.h, thereby importing the file Hand.h before getting up to the declaration of the Deck class), this can be solved by forward declarations.
I see you already have a forward declaration of the Card class ("class Card;"). Therefore, do you really need to #include "Card.h"? If you remove that include, you can still refer to the class Card due to the forward declaration, but it may resolve the cyclic dependency.
I usually don't #include .h files from other .h files in C++ unless I really have to. If you are just referring to a class in another file (by pointer, reference, or putting it in a container like vector), then you can get away with just forward-declaring the class, and physically including the header file from the .cpp file only.