Home > Enterprise >  "Pointer to incomplete class type is not allowed"
"Pointer to incomplete class type is not allowed"

Time:11-22

For some reason I cannot use the "getNotify()" function attached to the "Broker" object. I added a comment to the line that is not working(in "Publisher" class). As an error I get "Error; pointer to incomplete class type is not allowed" Please help

the "Broker" class is implemented with Singleton-Pattern Broker.h class:

#ifndef DEF_Broker
#define DEF_Broker
#include <iostream>
#include "classes.h"

using namespace std;


class Broker : Publisher
{
    static Broker *instance;
    Broker();

    public:
        static Broker* getInstance()
        {
            if(!instance)
            {
                instance = new Broker();
            }
            return instance;
        }

        void getNotify()
        {   
            for(auto sub : SubscriberList)
            {
                if(t.msg == "Hello World")
                {
                    SubCount  ;
                    cout << SubCount << " - ";
                    sub->update(t.msg);
                }
                else if(t.msg == "Ping")
                {
                    cout << "Ping" << endl;
                    sub->update("Pong");
                }
            }
        }
};
Broker *Broker::instance = 0; // Null, because instance will be initialized on demand.

Broker::Broker(){}; // Private constructor so that no objects can be created.


#endif

classes.h :

#ifndef DEF_classes
#define DEF_classes
#include <iostream>
#include <list>

using namespace std;

class Broker;

class Subscriber
{
    public:
        void update(string msg)
        {
            cout << msg << endl;
        }

};

class Topic
{
    public:
        string msg;
        Topic(){};
        Topic(string msg)
        {
            this->msg = msg;
        }
};

class Publisher
{
    protected:
        list<Subscriber*> SubscriberList;
        static int SubCount; 
    
    public:
        Topic t;
        Broker *broker;// = broker->getInstance();
        Publisher(){}
        Publisher(Topic t)
        {
            this->t = t;
        };

        void AddSub(Subscriber *sub)
        {
            SubscriberList.push_back(sub);
        }

        void notify(string msg)
        {
            broker->getNotify(); // this not working
        }
};
int Publisher::SubCount = 0; // Initialize static member SubCount

#endif

CodePudding user response:

Normally you would need to include broker.h in classes.h, however, this would create a circular dependency.

Therefore, implement the functions of Publisher in a .cpp file and include broker.h in that file. The forward declaration in classes.h (class broker;) needs to remain.

CodePudding user response:

One possible way to solve this would be to create different files(headers and source files) for different classes. I have done this for you in this case so that you can take this example as a reference(starting point) for your future purposes/programs. Below are all the files:

Borker.h

#ifndef DEF_Broker
#define DEF_Broker
#include <iostream>
#include "Publisher.h"

class Broker : Publisher
{
    static Broker *instance;
    Broker();

    public:
        static Broker* getInstance()
        {
            if(!instance)
            {
                instance = new Broker();
            }
            return instance;
        }

        void getNotify();
        
};

#endif

Broker.cpp

#include "Broker.h"
#include "Subscriber.h"
Broker *Broker::instance = 0; // Null, because instance will be initialized on demand.
void Broker::getNotify()
{   
    for(auto sub : SubscriberList)
    {
        if(t.msg == "Hello World")
        {
            SubCount  ;
            std::cout << SubCount << " - ";
            sub->update(t.msg);
        }
        else if(t.msg == "Ping")
        {
            std::cout << "Ping" << std::endl;
            sub->update("Pong");
        }
    }
}


Broker::Broker()
{
    
}; // Private constructor so that no objects can be created.

Topic.h

#ifndef TOPIC_H
#define TOPIC_H
#include <iostream>
#include <list>
#include <string>


class Topic
{
    public:
        std::string msg;
        Topic(){}
        Topic(std::string msg);
        
};

#endif

Topic.cpp

#include "Topic.h"
Topic::Topic(std::string msg)
{
    this->msg = msg;
}

Publisher.h

#ifndef PUBLISHER_H
#define PUBLISHER_H
#include <list>
#include "Topic.h"
class Broker;//needed for Borker *broker
class Subscriber;//needed for Subscriber*
class Publisher
{
    protected:
        std::list<Subscriber*> SubscriberList;
        static int SubCount; 
    
    public:
        Topic t;
        Broker *broker;// = broker->getInstance();
        Publisher(){}
        Publisher(Topic t)
        {
            this->t = t;
        };

        void AddSub(Subscriber *sub);

        void notify(std::string msg);
        
};

#endif

Publisher.cpp

 #include "Publisher.h"
 #include "Broker.h"//needed for broker->getNotify()
int Publisher::SubCount = 0; // Initialize static member SubCount
void Publisher::notify(std::string msg)
{
    broker->getNotify(); // this not working
}
void Publisher::AddSub(Subscriber *sub)
{
    SubscriberList.push_back(sub);
}

Subscriber.h

#ifndef SUBSCRIBER_H
#define SUBSCRIBER_H
#include <string>
class Subscriber
{
    public:
        void update(std::string msg);

};

#endif

Subscriber.cpp

 #include "Subscriber.h"
 #include <iostream>
 void Subscriber::update(std::string msg)
{
    std::cout << msg << std::endl;
}

The program compiles successfully as can be seen here.

CodePudding user response:

@Ben @AnnopRana thanxs guys. I got inspired from ur answers and i got the following solution

broker.h

#ifndef DEF_Broker
#define DEF_Broker
#include <iostream>
#include "classes.h"

using namespace std;


class Broker
{
    static Broker *instance;
    Broker();

    public:
        Publisher pub;
        static Broker* getInstance()
        {
            if(!instance)
            {
                instance = new Broker();
            }
            return instance;
        }

        void getNotify()
        {  
            for(auto sub : pub.SubscriberList)
            {
                if(pub.t.msg == "Hello World")
                {
                    pub.SubCount  ;
                    cout << pub.SubCount << " - ";
                    sub->Subscriber::update(pub.t.msg);
                }
                else if(pub.t.msg == "Ping")
                {
                    cout << "Ping" << endl;
                    sub->Subscriber::update("Pong");
                }
                else
                {
                    cout << "no such as topic" << endl;
                }
            }
        }
};
Broker *Broker::instance = 0; // Null, because instance will be initialized on demand.

Broker::Broker(){}; // Private constructor so that no objects can be created.


#endif

classes.h

#ifndef DEF_classes
#define DEF_classes
#include <iostream>
#include <list>

using namespace std;

class Broker;

class Subscriber
{
    public:
        void update(string msg)
        {
            cout << msg << endl;
        }

};

class Topic
{
    public:
        string msg;
        Topic(){};
        Topic(string msg)
        {
            this->msg = msg;
        }
};

class Publisher
{
    public:
        list<Subscriber*> SubscriberList;
        static int SubCount;     
        Topic t;
        Publisher(){}
        Publisher(Topic t)
        {
            this->t = t;
        };

        void AddSub(Subscriber *sub);

        void notify(Broker *b);
};


#endif

publisher.cpp

#include "classes.h"
#include "Broker.h"//needed for broker->getNotify()

using namespace std;

int Publisher::SubCount = 0; // Initialize static member SubCount

void Publisher::notify(Broker *b)
{
    b->getNotify(); 
}

void Publisher::AddSub(Subscriber *sub)
{
    SubscriberList.push_back(sub);
}
  • Related