PDA

View Full Version : Forward declarations needed for some?



doktorn
20th November 2007, 09:16
Hello.

This is a question to still my curiosity about forward declarations. According to Blanchette and Summerfield's book, forward declarations is needed only to make compilation "somewhat faster". But I just got problems for not having them onboard in my program.


incomehandler.h:21: error: ISO C++ forbids declaration of `QLabel' with no type
incomehandler.h:21: error: expected `;' before '*' token


I commented after the declaration in question in the code below, and since the compiler doesn't go on strike now even if I still haven't forward-declared the QPushButton.

Why is The QLabel more sensitive than QPushButton?



#ifndef INCOMEHANDLER_H
#define INCOMEHANDLER_H

#include <QDialog>

class QLabel; //With this row my prorgam compiles, without it i get the error posted above.

class IncomeHandler : public QDialog
{
Q_OBJECT

public:
IncomeHandler(QWidget *parent = 0);
signals:

private slots:
void okClicked();

private:
QLabel *activeLabel;
QPushButton *okButton;

};

#endif

DeepDiver
20th November 2007, 09:21
just have a look into the headers included QPushButton is foreward declared already.
QLabel is not.

doktorn
26th November 2007, 13:21
OK. So it seems forward declarations are necessary always. Thanks! :)

wysota
26th November 2007, 13:33
No. Forward declaring a class is an alternative to including its header file. In that meaning forward declarations improve the compilation speed compared to including a header file.

doktorn
27th November 2007, 10:30
OK. So when should I rather include the header file than making a forward declaration?

wysota
27th November 2007, 10:43
When you need to know the size of the class defined in the header file. You can only forward declare classes you will be using as pointers. If you want to have an object, you need a full definition:

class X {
QPushButton *b;
QLabel l;
};
In this situation you can forward declare QPushButton (because the size of the pointer is known so you don't need to know the size of the complete object) but you can't forward declare QLabel. Of course you also need full definitions (hence include the header) if you want to use methods of the class in question (for example in implementation files).

rickbsgu
28th November 2007, 08:56
You basically need to include the header if the code needs to know anything about the class.

Otherwise, you can just do a forward declaration.

This applies to header or source files.




#include "Y.h"
#include "Z.h"
// includes

class W;
// forward declaration

class X
{
public:

Y y;
// embedded class - you need the header.

W *w;
// pointer - you *may* need the header

static Z *z;
// singleton - we'll need the header, because we're going to
// allocate an instance.

Z *getZ()
{
if (!z)
z = new Z();
// (here's the allocation)

return z;
}

void doSomethingWithZMember()
{
getZ();
doSomething(z->member);
// we need a header, because we're using a member.
// this would be true whether we allocated z here or not.
}

void doSomethingWithWZ()
{
doSomething(w);
doSomething(getZ());
// don't need headers to just pass pointers around.
// (but in this instance, we need the Z header to do the above
// ops)
}

void doSomething(int){}
void doSomething(Z *){}
void doSomething(W *){}
};



If the function bodies were moved down into the .cpp files (including the accessor), you could use forward declarations for Z (but not Y). You probably wouldn't, though, because X is intimately tied with Z...

It depends.

rickb