C++ Compiler Error; Namespace issue I guess - c++

The error I get is "No member named detail in namespace ChessGame. Here is the relevant code
//ChessPiece.h
namespace ChessGame
{
class ChessBoard;
namespace detail
{
class IChessPieceEnums{
public:
enum PieceType{PAWN, KNIGHT, BISHOP, ROOK, QUEEN, KING};
enum PieceDirection{ UP = 1 , DOWN = -1};
enum PieceId{ WHITE_PIECE_ID, BLACK_PIECE_ID };
};
}
//represents an abstract chess piece interface
class IChessPiece : public detail::IChessPieceEnums
{
public:
///...
}
} // end namespace
//GameBoard.h
#include "ChessPiece.h"
namespace ChessGame
{
class IChessPiece;
class ChessBoard
{
public:
/*********ERROR OCCURS ON THIS FUNCTION************/
bool isOccupiedWithEnemy(int row, int col,const ChessGame::detail::IChessPieceEnums::PieceId& pieceId);
}
}
Any idea guys?
EDIT: Another minimal example :
//Piece.h
#ifndef TestProject_C___Piece_h
#define TestProject_C___Piece_h
#include "Board.h"
namespace Foo {
namespace detail{
struct PieceEnums{
enum PieceID{ ID1, ID2 };
};
}
class Board;
class Piece{
public:
void foo(Board& b)const;
};
}
#endif
//board.h
#ifndef TestProject_C___Board_h
#define TestProject_C___Board_h
#include "Piece.h"
namespace Foo {
class Piece;
class Board{
bool isOcc(int x, int y,const detail::PieceEnums::PieceID pid)const;
};
}
#endif
And the error is 'Use of undeclared identifier detail
Note that this is across multiple files, so maybe its a problem with linkage?

To specify the desired name directly, say either detail::IChessPieceEnums::PieceId or ::ChessGame::detail::IChessPieceEnums::PieceId, but preferably the former. However, your present syntax is actually fine, too, since search resumes in the global namespace if a name can't be found.

Ok found a solution. The solution is to put the namespace detail in its own file called detail.h. That way, piece.h and board.h needs to include details.h to use it. That worked.
And the problem with the original post is that there is a circular reference. That is causing trouble somehow. Would love an explanation.

Related

(solved) field has incomplete type of class

I´m building a program with several classes (data structures like stacks, lists,etc).
There is some class (Concesionario) that i need to use in another (ListaE). The class ListaE uses another class called NodoListaE, which uses two pointers, one to the value of the object (Concesionario) and another to the next position of the list (siguiente).
#ifndef NODOLISTAE_HPP
#define NODOLISTAE_HPP
#include "Concesionario.hpp"
class Concesionario;
class ListaE;
class NodoListaE
{
public:
NodoListaE(Concesionario* conc, NodoListaE* sig = NULL);
private:
Concesionario* conc;
NodoListaE* siguiente;
friend class ListaE;
};
typedef NodoListaE* pnodoListaE;
#endif // NODOLISTAE_HPP
#ifndef LISTAE_HPP
#define LISTAE_HPP
#include "NodoListaE.hpp"
#include "Automovil.hpp"
class Automovil;
class NodoListaE;
class ListaE
{
private:
NodoListaE* primero;
public:
ListaE();
void enlistarOrden(Automovil* automovil);
};
#endif // LISTAE_HPP
#ifndef CONCESIONARIO_HPP
#define CONCESIONARIO_HPP
#include <string>
#include "ListaE.hpp"
class ListaE;
class Concesionario
{
public:
Concesionario();
~Concesionario();
std::string mostrar();
void setZona(std::string letra);
void setNum();
int getNum();
private:
int nc=2;
int num_conc;
std::string zona;
int generadorNumsIntervalo(int min, int max);
ListaE automoviles;//ERROR HERE
};
#endif // CONCESIONARIO_HPP
All the cpp files are not implemented (empty constructor and destructor).
The compiler I´m currently using is MINGWx64.
I´ve tried using forward declarations and it worked for the rest of the classes but not for this one.
The program throws the following error in the **Concesionario ** hpp file: include\Concesionario.hpp|22|error: field 'automoviles' has incomplete type 'ListaE'|
Concesionario is implemented in other classes and the program runs perfectly.
Example of another class implementing Concesionario
#ifndef ARBOL_HPP
#define ARBOL_HPP
#include <iostream>
#include "NodoArbol.hpp"
#include "Concesionario.hpp"
using namespace std;
class Arbol {
public:
Arbol();
void Insertar(Concesionario* concesionario);
private:
pnodoArbol raiz;
pnodoArbol actual;
int contador;
int altura;
bool Vacio(pnodoArbol nodo);
};
#endif // ARBOL_HPP
I`ve also tried deleting this class and creating another one from 0 but the error remains.
Any solution to this problem? Thank you very much.

expected class-name before '{' token - with header files and cpp files

Like many people asking this question, I am very new to C++ and I can't wrap my head around this error:
Dollar.h:4:31: error: expected class-name before '{' token
class Dollar: public Currency {
These are my files
main.cpp
#include <iostream>
#include "Dollar.h"
using namespace std;
int main() {
Dollar * d = new Dollar();
d->printStatement();
return 0;
}
Currency.cpp
#include <iostream>
#include "Currency.h"
using namespace std;
class Currency {
public:
virtual void printStatement() {
cout << "I am parent";
}
};
Currency.h
#ifndef CURRENCY_H
#define CURRENCY_H
class Currency {
public:
virtual void printStatement();
};
#endif
Dollar.cpp
#include <iostream>
using namespace std;
void printStatement() {
cout << "I am dollar";
}
Dollar.h
#ifndef DOLLAR_H
#ifndef DOLLAR_H
class Dollar : public Currency {
public:
void printStatement();
};
#endif
Thank you so much for your time and any help is much appreciated.
The error says that the name of a class was expected between : public and { here:
class Dollar : public Currency {
^^^^^^^^
Currency is not a name of a class, because you haven't defined such class. Yes, you have defined such class in files Currency.cpp and Currency.h, but not in the file Dollar.h where that error occurs.
Solution: The class Currency has to be defined first before it can be used as a base class. Like so:
// class is defined first
class Currency {
public:
virtual void printStatement();
};
// now Currency is a class and it can be used as a base
class Dollar : public Currency {
public:
void printStatement();
};
Since a class must be defined in all source files where it is used, and the definition must be identical across all source files, it is often useful to define the class in a separate "header" file, such as you have done. In such case you can simply include that header in stead of writing the definition repeatedly in each source file:
#include "Currency.h"
Currency.cpp contains two definitions for the class Currency. Once in the header that is included, and then second time after that. You may not have multiple definitions for the same class in a single source file.
Solution: Remove the class definition from Currency.cpp. Instead only define the member function:
void Currency::printStatement() {
//...
}
Finally, you haven't defined Dollar::printStatement. You've defined printStatement, which is not the same thing.
In my case, I had two classes with same name but in two different namespaces.
So, changing the base class to something different solved the problem.

Troubles with Circular Dependencies between 3 classes and with inheritance

I'm a first-year college student that doesn't know everything about CS yet, so please bear with my newness to it, and this is my first question on here.
For an assignment, we are making faux version of Pokemon Go to practice using polymorphism in c++, and I'm running into some compiler errors. Here are the three files with just a sample of the code in them:
#ifndef EVENT_H
#define EVENT_H
#include <string>
#include "Trainer.h"
class Event{
protected:
std::string title;
public:
Event();
~Event();
virtual void action(Trainer) = 0;
};
#endif
Trainer.h:
#ifndef TRAINER_H
#define TRAINER_H
#include "Pokemon.h"
class Trainer{
private:
Pokemon* pokemon;
int num_pokemon;
public:
Trainer();
~Trainer();
//include accessors and mutators for private variables
};
#endif
Pokemon.h:
#ifndef POKEMON_H
#define POKEMON_H
#include "Event.h"
#include <string>
class Pokemon : public Event{
protected:
std::string type;
std::string name;
public:
Pokemon();
~Pokemon();
virtual bool catch_pokemon() = 0;
};
#endif
The trainer.h file is a parent class for each pokemon type (eg Rock) which just defines a few virtual functions. The error I'm getting is when I'm compiling all of this and I get something that says:
Pokemon.h : 5:30: error: expected class-name befoer '{' token:
class Pokemon : Event {
Pokemon need to be a derived class to an event, so that an event pointer can point in another Location class can point to either a pokemon, pokestop, or cave for the assignment, and I have been looking online for hours and can't figure out what to do. I would appreciate the help! Let me know if you need more info or something because again, this is my first time posting a question.
You need some forward declarations.
In Event.h, you can put class Trainer; instead of #include "Trainer.h". In Trainer.h, you can put class Pokemon; instead of #include "Pokemon.h".
You will probably need to include the appropriate headers in the corresponding source files in order to actually use the other classes. But by avoiding the includes in the header files, you get out of the circular dependency trouble.
Pokemon.h must continue to #include "Event.h", since you're inheriting Event, which requires a complete definition.
Use forward declaration, to tell classes the type they need to use will be defined later. You can use forward declaration in situations where the size is know, pointers and references are always the same size regardless of the type they point to so use them.
#ifndef EVENT_H
#define EVENT_H
#include <string>
class Trainer;
class Event
{
protected:
std::string title;
public:
Event();
virtual ~Event();
virtual void action(Trainer* const trainer) = 0;
};
#endif
then
#ifndef TRAINER_H
#define TRAINER_H
class Pokemon;
class Trainer
{
private:
Pokemon* const pokemon;
int numPokemon;
public:
Trainer();
~Trainer();
};
#endif
then
#ifndef POKEMON_H
#define POKEMON_H
#include "Event.h"
#include <string>
class Pokemon : public Event
{
protected:
std::string type;
std::string name;
public:
Pokemon();
virtual ~Pokemon();
virtual bool catchPokemon() = 0;
};
#endif
when using polymorphism (virtual functions) you must always make the base class destructor virtual too. It is also nice to make the derived classes destructor virtual as well, but it is not required.

How to use forward declaration in the following scenario

I currently have the following two classes
class TOrder
{
public:
private:
.......
};
Now my other class is :
#include "TOrder.h"
namespace namespaceA
{
namespace namespaceB
{
class OrderDis
{
private:
TOrder* frmPointer;
.....
};
}
}
The above works fine the problem starts when I use an object of OrderDis in TOrder as such
#include <QMainWindow>
#include "OrderDis" //Added - Creates Problem
class TimedOrder
{
public:
.......
};
Any suggestion on how I could use forward declaration to resolve my issue ?
You could forward OrderDispatcher in TimeOrder.h
namespaceA
{
namespaceB
{
class OrderDispatcher;
}
}
class TimedOrder
{
//...
};
The forward declaration can be written as:
namespace A{ namespace B{ class OrderDispatcher; } }
As you only use a pointer to TimedOrder in the OrderDispatcher class, it can be solved by simply not including TimedOrder.h in the OrderDispatch.h file. Instead just declare the TimedOrder class:
class TimedOrder;
No need to muck about with namespaces and such then.
Note: You can't declare it in any of the namespaces, declare it instead where you now do your #include.

inheritance from class,defined in th different namespace

I have 2 classes ,defined in the different namespaces :
//--==file1.hpp==--
namespace n1{
class x1 {
//.....
};
};
//--==file2.hpp==--
namespace n2{
class x1: public n1::x1{
//.....
};
};
//--== file3.hpp ==--
namespace n2 {
class x2 {
private:
n1::x1* data1_;
public:
void func(x1* data2) { data1_ = data2; }
};
};
The compilation of this fails with
error C2440: '=' : cannot convert from `'n2::x1 *' to 'n1::x1 *'`
I can`t understand what could be a problem,Since n2:x1 inherits from n1::x1...?
Thank you
Inheritance from one namespace to another namespace class, should not have any compilation error. It is just that, in the sub-class, if you have to call the method of the parent class (which is in another namespace), you should use the complete name (with namespace).
For you reference:
namespace a
{
class A1 {
public:
void testA1() {...}
};
}
namespace b
{
class B1: public class a::A1
{
public:
void testB1()
{
a::A1::testA1();
...
}
};
}
But looks like, the above problem was just been a typo issue, and has been resolved. However, to clarify on the usage, sample code shall help.
In file2.h: Include file1.h
In file3.h: Include file1.h and file2.h.
And in main include file3.h.
int main()
{
n2::x2 xx22;
n2::x1* xx11;
xx22.func(xx11);
}
This complies just fine.