Search code examples
c++visual-studioclasscontainersc2079

Message::simbolo uses undefined class Symbol


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();
};


Solution

  • 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.