forward declaration of classes

H

HappyHippy

Hi,

I have a question about forward declaration of classes.
First of all, a simple working example, which compiles and works with no
problems.

///file class_a.h:/
#ifndef __CLASS_A_H__
#define __CLASS_A_H__

class classA
{
public:
int getX() const
{
return m_nX;
}
void setX(int nX)
{
m_nX = nX;
}
private:
int m_nX;
};

#endif

///file class_b.h:/
#ifndef __CLASS_B_H__
#define __CLASS_B_H__

*class classA; //forward declaration of classA class*

class classB
{
public:
classB(classA *pA): m_pA(pA){}
int getData() const;
void setData(int nData);
private:
classA *m_pA;
};

#endif

///file class_b.cpp:/
#include "class_b.h"
*#include "class_a.h" //here we need to include "class_a.h"*

int classB::getData() const
{
if(m_pA)
return m_pA->getX();

return -1; //let's assume, -1 is an error code
}

void classB::setData(int nData)
{
if(m_pA)
m_pA->setX(nData);
}

It is enough to just put "class classA;" in class_b.h file, since classB
does not have classA members (only pointer-to-classA member), so forward
declaration is enough for compiler, and "#include "class_a.h" is needed
only in implementation file.
That's fine, BUT...

Often you can see a class or a struct declared as:

///file class_a.h:/

#ifndef __CLASS_A_H__
#define __CLASS_A_H__

typedef class
{
public:
int getX() const
{
return m_nX;
}
void setX(int nX)
{
m_nX = nX;
}
private:
int m_nX;
} TClassA;

#endif

In this case the previous approach (all other files are the same) does
not work...
MS VC++ 7.1 gives me the following output:
class_a.h(17) : error C2371: 'classA' : redefinition; different basic types
class_b.h(1) : see declaration of 'classA'
class_b.cpp(7) : error C2027: use of undefined type 'classA'
class_b.h(1) : see declaration of 'classA'
class_b.cpp(7) : error C2227: left of '->getX' must point to
class/struct/union
class_b.cpp(15) : error C2027: use of undefined type 'classA'
class_b.h(1) : see declaration of 'classA'
class_b.cpp(15) : error C2227: left of '->setX' must point to
class/struct/union

So, my question is: Is there any way to use forward declaration for
classA to avoid using '#include "class_a.h"' in class_b.h file in the
second case?

Thank you!
 
V

Victor Bazarov

First of all, use _plain text_ to post here.
I have a question about forward declaration of classes.
First of all, a simple working example, which compiles and works with no
problems.

You are lucky. You used reserved identifiers in your code and got away
with it (so far, at least according to you). You should be careful, you
know.
///file class_a.h:/
#ifndef __CLASS_A_H__
#define __CLASS_A_H__

The identifier '__CLASS_A_H__' is reserved. Just drop the damn leading
and trailing underscores to make it legitimate.
class classA
{
public:
int getX() const
{
return m_nX;
}
void setX(int nX)
{
m_nX = nX;
}
private:
int m_nX;
};

#endif

///file class_b.h:/
#ifndef __CLASS_B_H__
#define __CLASS_B_H__

Again, reserved identifiers.
*class classA; //forward declaration of classA class*

My guess is the asterisk is what Netscape inserts to indicate "bold".
Yet another reason to post _plain text_.
class classB
{
public:
classB(classA *pA): m_pA(pA){}
int getData() const;
void setData(int nData);
private:
classA *m_pA;
};

#endif

///file class_b.cpp:/
#include "class_b.h"
*#include "class_a.h" //here we need to include "class_a.h"*

int classB::getData() const
{
if(m_pA)
return m_pA->getX();

return -1; //let's assume, -1 is an error code
}

void classB::setData(int nData)
{
if(m_pA)
m_pA->setX(nData);
}

It is enough to just put "class classA;" in class_b.h file, since classB
does not have classA members (only pointer-to-classA member), so forward
declaration is enough for compiler, and "#include "class_a.h" is needed
only in implementation file.
Correct.

That's fine, BUT...

Often you can see a class or a struct declared as:

///file class_a.h:/

#ifndef __CLASS_A_H__
#define __CLASS_A_H__

typedef class
{
public:
int getX() const
{
return m_nX;
}
void setX(int nX)
{
m_nX = nX;
}
private:
int m_nX;
} TClassA;

#endif

In this case the previous approach (all other files are the same) does
not work...
Correct.

MS VC++ 7.1 gives me the following output:
class_a.h(17) : error C2371: 'classA' : redefinition; different basic types
class_b.h(1) : see declaration of 'classA'
class_b.cpp(7) : error C2027: use of undefined type 'classA'
class_b.h(1) : see declaration of 'classA'
class_b.cpp(7) : error C2227: left of '->getX' must point to
class/struct/union
class_b.cpp(15) : error C2027: use of undefined type 'classA'
class_b.h(1) : see declaration of 'classA'
class_b.cpp(15) : error C2227: left of '->setX' must point to
class/struct/union

So, my question is: Is there any way to use forward declaration for
classA to avoid using '#include "class_a.h"' in class_b.h file in the
second case?

No.

Victor
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,011
Latest member
AjaUqq1950

Latest Threads

Top