chrise chrise - 2 months ago 6
C++ Question

pre-defining classes not working when using pointers to classes

I am trying to implement a listener. Because of many cross-references I am trying to avoid including other classes and pre-define them

My listener looks as follows

.h

class Book
{
public:
Book();
private:
std::vector<MyListener *> listeners_;
void Notify();
}


.cpp

Book::Book() {}

void Book::Notify() {

MyListener *p_listener;

for ( int i = 0; i < this->listeners_.size(); i++ ) {

p_listener = listeners_[i];
p_listener->Update(); // ERRORS THROWN HERE WHEN NOT INCLUDING LISTENER.H

}
}


This all works fine when I include the listener.h file

#include "listener.h"


But when I instead pre-declare Listener it doesnt work

class Listener;


It gives me the two errors

C:\CPP\qtTradeSim\qtTradeSim\test\book.cpp:33: error: C2027: use of undefined type 'Listener'
C:\CPP\qtTradeSim\qtTradeSim\test\book.cpp:33: error: C2227: left of '->Update' must point to class/struct/union/generic type


Is there a way to avoid including the Listener header?

xis xis
Answer

Let's suppose the compiler sees the following code:

class Listener;

std::vector<Listener*> pListeners;

// some code...

for(auto& pListener: pListeners) {
    pListener->update();
}

Note, how does the compiler see the Listener has a member function update? The symbol update could not be determined until the compiler see the Listener full declaration. Think if you used update with an argument missing, could the compiler capture this problem without seeing the declaration of update? Thus, it cannot translate the code. If you give a full declaration of the Listener, e.g.

class Listener {
public:
    Listener() { // some construction
    }
    void update() {
        // dosth
    }
};

The compiler could know the update method, its parameters, the return value, etc., and compile it happily.