# Forward declaration, undefined type

This topic is 4719 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

In keeping with my self appointed tradition of distilled examples, I present the following:
class B; //forward declaration to use type:B in A

class A {
friend class B;
public:
A(B * bptr = A::sbptr){
A::sbptr=bptr;
}

void addProperty(const std::string & s, int i) {
properties[s] = i;
A::sbptr->addAByProperty(s, this); //line in question
}

private:
std::map < const std::string, int > properties;
static B * sbptr;
};
B* A::sbptr=0;

class B {
public:
void setAsCurrent() {
A::sbptr = this;
}

std::list < A * > getAsByProperty(const std::string & s) {
return a_map[s];
}

private:
void addAByProperty(const std::string & s, A * aptr) {
a_map[s].push_back(aptr);
}

std::map < const std::string, std::list < A * > > a_map;
};

int main(int /* argc */, char * /* argv */ []) {
B b1;
b1.setAsCurrent();

A a1;

std::cin.get();
}
//mingw/gcc 3.4.2


I'm at a loss as to why I can't use sbptr->addAByProperty(s, this); inside of A. class B is declared with a forward declaration. It should work perfectly, IMHO. ;) I havn't delved into design patterns, but maybe there is one that can fit my case?

##### Share on other sites
It seems this question gets asked once a day..

Before you can invoke any of B's members, its definition must first be given. No exceptions.

Your forward declaration of B only tells the compiler that it exists somewhere - which is why you are able to define sbptr in class A, but are not able to call the method addAByProperty() using it.

This is why it is a good idea to always specify a class definition in its own header file, and its implementation in a source file.

##### Share on other sites
If A's member function definitions are moved to a source file, they can be given a complete declaration of both A and B, and then it will work.

##### Share on other sites
Quote:
 Original post by WavarianIt seems this question gets asked once a day..

Now, now...be nice to the poor programmer. Maybe he asks the question because he doesn't know the answer?

For situations such as this, this article tells you what you need to know. It's a bit of a long read, but worth it because that's what the programmers who know what they're doing do.

To distill it a bit:
You should nearly always place your class definitions in a header (.h or .hpp) file, with prototypes and member variables. Then place the actual function definition in a source (.c or .cpp) file. (The major exception to this rule being templates, but that doesn't apply in your situation.)

In any case, the advice already given is good. What you would do in this instance is create a header file "A.h" for class A:
class B; //forward declaration to use type:B in Aclass A{    friend class B;public:    A(B * bptr);    void addProperty(const std::string & s, int i);private:    std::map < const std::string, int > properties;    static B * sbptr;};

and a source file for class A:
#include "B.h"#include "A.h"A::A(B * bptr = A::sbptr){    A::sbptr = bptr;}void A::addProperty(const std::string & s, int i){    properties[s] = i;    A::sbptr->addAByProperty(s, this); //line in question}

as well as header and source for class B:
class A;class B{public:    void setAsCurrent();    std::list < A * > getAsByProperty(const std::string & s);private:    void addAByProperty(const std::string & s, A * aptr);    std::map < const std::string, std::list < A * > > a_map;};

#include "B.h"#include "A.h"void B::setAsCurrent(){    A::sbptr = this;}std::list < A * > B::getAsByProperty(const std::string & s){    return a_map[s];}void addAByProperty(const std::string & s, A * aptr){    a_map[s].push_back(aptr);}

As you can see, this makes it so that header files only need the forward declaration, and source files can include the header files they need for full functionality.

Cheers,
Twilight Dragon

##### Share on other sites
Thank you very much. I've used forward declaractions before but this situation has never come up before.

ratings++ to everyone.

• 16
• 11
• 9
• 49
• 12
• ### Forum Statistics

• Total Topics
631392
• Total Posts
2999738
×