Namespace problem (I think 1!)

Hello,

I'm getting an 'XXX undeclared error when I try to compile with the following two header files (I've not included the C++ code as I don't think it's relevant to the error) :

accelerometerframe.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#ifndef ACCELEROMETERFRAME_H
#define ACCELEROMETERFRAME_H

#include <QtGui/QFrame>
#include "phidgetaccelerometer.h"

namespace Ui {
    class AccelerometerFrame;
}

class AccelerometerFrame : public QFrame {
    Q_OBJECT
public:
    AccelerometerFrame(QWidget *parent = 0);
    ~AccelerometerFrame();
    void setPhidgetAccelerometer(PhidgetAccelerometer* p); //<<< compile error here


protected:
    void changeEvent(QEvent *e);

private:
    Ui::AccelerometerFrame *m_ui;
    //AccelerometerFrame *m_ui;
    PhidgetAccelerometer* pA;

};

#endif // ACCELEROMETERFRAME_H 


phidgetaccelerometer.h :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#ifndef PHIDGETACCELEROMETER_H
#define PHIDGETACCELEROMETER_H

#include <QObject>
#include <map>
#include "interface_phidgetmodule.h"
#include "accelerometerframe.h"



class PhidgetAccelerometer : public Interface_PhidgetModule
{
public:
    PhidgetAccelerometer();
    ~PhidgetAccelerometer();
    PhidgetAccelerometer(const PhidgetAccelerometer& orig);
    PhidgetAccelerometer(const CPhidgetHandle hnd);


    /*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*
     * Virtual functions declared
     * in the base class
     *^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*^*/
    virtual int createHandle();
    virtual int onDetachHandler();
    virtual int getSerialNumber(int*);
    virtual QString getDeviceType();

    int getSerialNumber(CPhidgetHandle hnd, int* serialNumber);
    virtual CPhidgetAccelerometerHandle getHandle();
    static int callBack(CPhidgetAccelerometerHandle phid, void *userPtr, int index, double acceleration);
    //void setAccelerometerFrame(AccelerometerFrame* aF);

private:
    void init();
    std::map<CPhidgetAccelerometerHandle,CPhidgetAccelerometerHandle*> accelerometers;
    virtual int open(CPhidgetHandle hnd, int serialNumber);
    CPhidgetAccelerometerHandle accel;
    CPhidgetHandle phidHnd;
    //AccelerometerFrame* aF;

};

#endif // PHIDGETACCELEROMETER_H 


Now the error I get is :

accelerometerframe.h:16: error: ‘PhidgetAccelerometer’ has not been declared


Now as I'm no expert programmer, as I've #included the appropriate header I'm thinking this is a namespace problem. acclerometerfram.h uses a namespace (which has been automatically generated, the class itself was generated by QT IDE which automatically generates a namespace for each class) whereas acclerometerframe.h was created from scratch by me and obviously has no namespace.

Is this where the problem lies or have I overlooked something (simple) ?
Circular dependendy!!!!

Each of these two header files are #including each other.

Relevent link:
http://cplusplus.com/forum/articles/10627/ <-- see section 4 and up. Section 6 covers this specific issue.


The solution is to opt for forward declaring rather than #including.

accelerometerframe.h
1
2
3
4
5
6
7
8
#ifndef ACCELEROMETERFRAME_H
#define ACCELEROMETERFRAME_H

#include <QtGui/QFrame>
//#include "phidgetaccelerometer.h"  <--- bad
class PhidgetAccelerometer;  // <---  good

//... 


This is unrelated, but you're also using namespaces wrong:

1
2
3
4
5
6
namespace Ui {
    class AccelerometerFrame;
}

class AccelerometerFrame : public QFrame {
//... 


This actually declares two classes. ::AccelerometerFrame (in the global namespace) and Ui::AccelerometerFrame (int he Ui namespace). These are NOT the same class.

If you want AccelerometerFrame to be in the Ui namespace, you put the whole thing in the namespace braces:

1
2
3
4
5
6
7
8
namespace Ui
{

class AccelerometerFrame : public QFrame {
 // ... 
};

} // namespace Ui 


Thanks Disch !

As for the use of namespaces, there is not much I can do about that; In my own written-from-scratch classes I have not used namespaces it's only in those classes automatically generated by QT Creator that implements namespaces in that manner so there's not much I can do about it but thanks for the info it's something for me to bear in mind for the future.
Actually, using forward declaring presents me with another problem now; As both objects interact i.e. call public member functions of each other I really need to #include, but then I get the circular dependency. Is the only solution to make the two classes one, or make them friend classes ?

I'd rather not make them all one class, as one represents the graphical (GUI) interface while the other is the 'under the bonnet' stuff... so while the 'under the bonnet stuff' will stay the same, I can change the GUI at a later date
There is never any situation where you need to have circular includes.

*points again to above link to article explaining all this*
http://cplusplus.com/forum/articles/10627/

1
2
3
4
5
6
7
8
// a.h
class B;

class A
{
  void foo();
  B* b;
};


1
2
3
4
5
6
7
8
// a.cpp
#include "a.h"
#include "b.h"

void A::foo()
{
  b->DoStuff();
}


repeat above pattern for b.h/b.cpp
Topic archived. No new replies allowed.