Message::simbolo uses undefined class Symbol - c++

Error C2079 'Message::simbolo' uses undefined class 'Symbol'
is generated on this line when compiling
Symbol simbolo;
This is my C++ code:
class Message
#pragma once
#include <string>
#include "Symbol.h"
#include "SharedEditor.h"
class SharedEditor;
class Symbol;
class Message
{
private:
SharedEditor* sender;
int action; //1 inserted 2 deleted
Symbol simbolo;
public:
Message();
Message(SharedEditor* sender, Symbol nuovosimbolo, int action);
~Message();
};
class Symbol
#pragma once
#include "SharedEditor.h"
#include <vector>
class SharedEditor;
class Message;
class Symbol
{
char character;
int siteID;
SharedEditor* generator;
std::vector<int> position;
public:
Symbol();
Symbol(char ch, SharedEditor* source, int ID, std::vector<int> pos);
~Symbol();
};
class SharedEditor:
#pragma once
#include "NetworkServer.h"
#include "Message.h"
#include "Symbol.h"
class Message;
class Symbol;
class SharedEditor
{
private:
NetworkServer& _server;
int _siteId;
std::vector<Symbol> _symbols;
//other functions
public:
SharedEditor(NetworkServer ns);
~SharedEditor();
void process(const Message& m);
};
class NetworkServer:
#pragma once
#include <iostream>
#include <vector>
#include <queue>
#include "SharedEditor.h"
#include "Message.h"
class SharedEditor;
class Message;
class NetworkServer
{
private:
std::vector<SharedEditor*> connected;
std::queue<Message> codaMessaggi;
public:
int connect(SharedEditor* sharedEditor);
void disconnect(SharedEditor* sharedEditor);
void send(const Message& m);
NetworkServer();
~NetworkServer();
};

You need to rework your various header files to break the dependency cycle.
The general rule is: if you only need pointers or references to a type T, you can get away with a forward declaration (class T;) instead of a full class declaration (class T { ... }, typically behind a #include).
For the example above I will go over each file and what you need:
Symbol.h needs a forward declaration of SharedEditor, as it only uses SharedEditor*.
Message.h needs a forward declaration of SharedEditor, but a full #include "Symbol.h" (compiler needs to know how big a Symbol is to calculate the size of Message)
SharedEditor needs a forward declaration of Message (passed as a reference), a full #include "NetworkServer.h" (passed as a parameter) and a full #include "Symbol.h" (used in a vector)
NetworkServer needs a forward declaration of SharedEditor (only used with pointers), but a full #include "Message.h" (used in a queue)
If you still have two classes that need full includes of each other, search stack overflow for "C++ dependency cycle" or somesuch.

Related

Using interface to export class from dll

IClass (My interface):
#ifndef _ICLASS_H
#define _ICLASS_H
#include <sstream>
namespace Test
{
class __declspec(dllexport) IClass
{
public:
virtual ~IClass() {}
virtual bool Init(const std::string &path) = 0;
};
}
#endif
Class.h
#ifndef _CLASS_H
#define _CLASS_H
#include "IClass.h"
#include <memory>
#include <sstream>
#include <stdio.h>
namespace Test
{
class Class: public IClass
{
public:
Class();
~Class();
bool Init(const std::string &path);
};
}
#endif
Class.cpp
#include "Class.h"
namespace Test
{
Class::Class()
{
}
bool Class::Init(const std::string &path)
{
try
{
// do stuff
return true;
}
catch(std::exception &exp)
{
return false;
}
}
}
main (in exe, dll linked implicitly)
#include "IClass.h"
using namespace Test;
int main(int argc, char* argv[])
{
std::shared_ptr<IClass> test = std::make_shared<Class>(); // error: unreferenced Class
test->Init(std::string("C:\\Temp"));
}
At the moment Class is not declared
-> if I include Class.h to main following error occurs: LNK2019: unresolved external symbol: add class __declspec(dllexport) Class : public IClass resolve this linker issue, but is it ok to do it this way?
-> I also can't do this: std::shared_ptr<IClass> test = std::make_shared<IClass>();
(because it's not allowed to create an object of abstract class)
How can I solve this issue and is this best practise?
If you want your EXE to allocate a new "Class" object, the EXE code has to know the Class type. If you want to keep the Class type unknown from the EXE, one solution may be to export from your DLL a factory function, which will construct a Class object and return it as an IClass pointer.
See How to implement the factory pattern in C++ correctly

sharing an object with multiple classes

I have 3 classes namely Board, Game, and AI
i want to have the object chessBoard of Board class to be use by Game and AI, and also by the Board Class. I want them to access that single chessBoard object (sharing)
problem is, it gives me the infamous fatal error LNK1169: one or more multiply defined symbols found. Also, there are Board.h,Game.h and AI.h (only declarations in them), and i also have their corresponding .cpp files. Each .h files have guards included (#ifndef _XXXXXX_H_)
I tried to include Board chessBoard inside Board.h file (just below the class), and it seems guards are not working.
Error 7 error LNK2005: "class Board chessBoard" (?chessBoard##3VBoard##A) already defined in AI.obj C:\Users\xxxx\Documents\Visual Studio 2010\Projects\CHESSv3\CHESSv3\Board.obj CHESSv3
Error 8 error LNK2005: "class Board chessBoard" (?chessBoard##3VBoard##A) already defined in AI.obj C:\Users\xxxxx\Documents\Visual Studio 2010\Projects\CHESSv3\CHESSv3\Game.obj CHESSv3
Error 9 error LNK2005: "class Board chessBoard" (?chessBoard##3VBoard##A) already defined in AI.obj C:\Users\xxxxx\Documents\Visual Studio 2010\Projects\CHESSv3\CHESSv3\ProgramEntryPoint.obj CHESSv3
AI.h
#ifndef _AI_H_
#define _AI_H_
#include <iostream>
#include <string>
using namespace std;
struct node {
string position;
string nextPosition;
float score;
int level;
float totalscore;
node* up;
node* right;
node* left;
bool approved;
string move;
};
class AI {
private:
//string board;
//string board[8][8];
int score1;
int maxscore;
int totalscore;
public:
void GetBoard(string[][8]);
void AnalyzeMyPositions();
void ExecuteAdvanceHeuristicMove();
};
#endif
Game.h
#ifndef _GAME_H_
#define _GAME_H_
#include <iostream>
#include <string>
#include <vector>
#include <sstream>
#include <queue>
#include <stack>
#include <cmath>
using namespace std;
class Game {
public:
char WhosTurn();
bool Playable();
bool GetMoveFromPlayer();
void TurnOver();
Game();
private:
char turn;
};
#endif
Board.h
#ifndef _BOARD_H_
#define _BOARD_H_
#include <iostream>
#include <string>
#include <vector>
#include <sstream>
#include <queue>
#include <stack>
#include <cmath>
using namespace std;
class Board {
public:
bool SquareChecker(string);
bool MoveChecker(string);
Board();
void PrintBoard();
int Execute(string);
void UnExecute();
string CB[8][8];
private:
char turn;
vector<string> BoardRecord;
stack<string> CBR;
//string CB[8][8];
};
Board chessBoard;
#endif
If you really want to do this, you need to make the declaration of the object extern in the header Board.h:
extern Board chessBoard;
You then provide a declaration in Board.cpp:
Board chessBoard;
Much better, though would be to create it in enclosing code and pass it (by reference) to the constructors of the other classes.
What you are looking for is the Singleton design pattern which can achieved in the following way:
// Board.h
class Board {
private:
static instance_;
public:
static Board *instance();
}
// Board.cpp
Board *Board::instance_ = NULL;
Board *Board::instance() {
if (!instance_)
instance_ = new Board();
return instance_;
}
Mind that this pattern can either be seen as good or bad, if you don't like using it you should consider passing the reference of an instantiated Board class to all the requiring ones and keep it stored in each object as an instance variable. Something like:
Game::Game() {
this->board = new Board();
this->ai = new AI(board);
// or better this->ai = new AI(this) so AI can access all game methods
}
Your problem could be that there could be 3 different chessBoard definitions because you might be adding 3 different #include "Board.h". Please make only a single object at a place where you have more control rather than creating it globally inside Board.h
Did you try it like this? Include the necessary include declarations only in the .cpp files.
//Board.h
class Board {};
//Game.h
class Board;
class Game {
Board* myBoard;
public:
void setBoard(Board*);
};
//AI.h
class Board;
class AI {
Board* myBoard;
public:
void setBoard(Board*);
};
void main() {
Board chessBoard;
Game g;
g.setBoard(&chessBoard);
AI ai;
ai.setBoard(&chessBoard);
}

unknown type error in C++

What is going on?
#include "MyClass.h"
class MyOtherClass {
public:
MyOtherClass();
~MyOtherClass();
MyClass myVar; //Unknown type Error
};
Suddenly when I include the .h and write that var Xcode gives me tons of errors... and also the unknown type error.
How can it be unknown when the .h is included right there?
Here is the NodeButton.h file which would correspond to the MyClass.h in the example
#pragma once
#include "cinder/Vector.h"
#include "cinder/gl/gl.h"
#include "cinder/gl/Texture.h"
#include "cinder/Color.h"
#include "cinder/ImageIo.h"
#include "cinder/Timeline.h"
#include "cinder/app/AppBasic.h"
#include "cinder/App/App.h"
#include "Node.h"
#include "CursorMano.h"
using namespace ci;
using namespace ci::app;
using namespace std;
using namespace is;
typedef boost::shared_ptr<class NodeButton> NodeButtonRef;
class NodeButton : public Node2D
{
public:
NodeButton (CursorMano *cursor, string imageUrl, bool fadeIn = false, float delay = 0.0f);
virtual ~NodeButton ();
//methods
void update( double elapsed );
void draw();
void setup();
//events
bool mouseMove( ci::app::MouseEvent event );
//vars
CursorMano *mCursor;
gl::Texture mImageTexture;
Anim<float> mAlpha = 1.0f;
bool mSelected = false;
private:
};
And here are the contents of CursorMano.h which would correspond to MyOtherClass.h in the example.
#pragma once
#include <list>
#include <vector>
#include "cinder/app/AppBasic.h"
#include "cinder/qtime/QuickTime.h"
#include "cinder/gl/Texture.h"
#include "cinder/Vector.h"
#include "NodeButton.h"
using namespace ci;
using namespace ci::app;
using namespace std;
class CursorMano {
public:
CursorMano (AppBasic *app);
~CursorMano ();
void mueveMano(Vec2i);
void update();
void draw();
void play(int button);
void reset(int button);
Vec2i mMousePos;
NodeButton mButtonCaller; //this gives the unknow type error
private:
AppBasic *mApp;
gl::Texture mFrameTexture;
qtime::MovieGl mMovie;
int mIdButton;
};
You have a circular dependency of your header files.
NodeButton.h defines NodeButton class which CursorMano.h needs to include so that compiler can see definition for NodeButton but NodeButton.h itself includes CursorMano.h.
You will need to use forward declarations to break this circular dependency.
In NodeButton.h you just use an pointer to CursorMano so You do not need to include the CursorMano.h just forward declare the class after the using namespace declarations.
using namespace std;
using namespace is;
class CursorMano;
It's probably a result of the circular dependency between you two header files (NodeButton includes CursorMano and CursorMano includes NodeButton). Try removing the #include "CursorMano.h" in NodeButton.h and add class CursorMano; before your NodeButton declaration.

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
{
...
};

Types are incomplete due to include guards

I am trying to get a project to compile, and I am running into a problem with incomplete types. Here is the output from make:
In file included from ../common/ClientCommunication.h:13,
from EchoService_stub.h:9,
from EchoService_stub.cpp:1:
../common/Naming_stub.h:16: error: field ‘clientCommunication’ has incomplete type
In file included from EchoService_stub.h:9,
from EchoService_stub.cpp:1:
../common/ClientCommunication.h:20: error: field ‘serverEndpoint’ has incomplete type
make: *** [EchoService_stub.o] Error 1
Here are my header files in question:
In Naming_stub.h:
ifndef NAMING_STUB_H__
#define NAMING_STUB_H__
#include <string>
#include <string.h>
#include "Naming.h"
class ClientCommunication;
class Naming_stub : public Naming {
private:
ClientCommunication clientCommunication;
protected:
// Protected Methods Here.
public:
// Public Methods Here.
};
#endif
In Naming.h
#ifndef NAMING_H__
#define NAMING_H__
#include "Remote.h"
#include "../util/RemoteException.h"
class Naming {
private:
protected:
public:
virtual Remote* lookup(std::string lookupURL) throw (RemoteException);
virtual void bind() throw (RemoteException);
~Naming();
};
#endif // NAMING_H__
Finally, there is the ClientCommunication.h file:
#ifndef CLIENT_COMMUNICATION_H__
#define CLIENT_COMMUNICATION_H__
#include <iostream>
#include <cstdlib>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include "../util/RemoteTypes.h"
#include "Naming_stub.h"
struct Endpoint;
class ClientCommunication {
private:
int socket_fd;
struct Endpoint serverEndpoint;
protected:
public:
ClientCommunication(const struct Endpoint& serverEndpoint_in);
struct Buffer send(struct Buffer& callBuffer);
~ClientCommunication();
};
#endif // CLIENT_COMMUNICATION_H__
Sorry that this is so long, but there is one more header file. The Endpoint struct is declare in RemoteTypes.h, which looks like the following:
#ifndef REMOTE_EXCEPTION_H__
#define REMOTE_EXCEPTION_H__
#include <netinet/in.h>
struct Endpoint {
int port;
char* service_id;
char* server_ip;
struct sockaddr_in host_name;
};
struct Buffer {
char* contents;
int size;
};
#endif
Thanks!
You cannot declare a field using an incomplete type. You have to declare a pointer instead.
private:
ClientCommunication clientCommunication; // requires #include
ClientCommunication *clientCommunication; // works with incomplete type
Otherwise, you have to include the client communication header in the first header.
ifndef NAMING_STUB_H__
#define NAMING_STUB_H__
#include "ClientCommunication.h"
ClientCommunication should be fully declared in Naming_stub.h before the declaration of Naming_stub, or its clientCommunication member should become a pointer/reference. Only those work with incomplete types. Similar advice applies to Endpoint in ClientCommunication.h.
As far as I can tell, you don't have #include "ClientCommunication.h" or #include "RemoteTypes.h" anywhere
So, #include "RemoteTypes.h" in ClientCommunication.h and #include "ClientCommunication.h" in Naming_stub.h