开发者

recursive definition in CPP [duplicate]

This question already has answers here: How to create two cl开发者_如何学编程asses in C++ which use each other as data? (2 answers) Closed 5 years ago.

I meet a problem like this: UPDATE

class A
{
public:
    A(){}
    int i;
    B b;
};

class B
{
public:
    B(){}
    int j;
    A a;
};

When I define it in one .h file, it would give an error. I think the problem is the recursive definition. But could someone help me how to solve such issue?

  1. error C2146: syntax error : missing ';' before identifier 'b' c:\users\xingyo\documents\visual studio 2010\projects\cppalgo\recudef\test1.h 9 1 RecuDef

  2. error C4430: missing type specifier - int assumed. Note: C++ does not support default-int c:\users\xingyo\documents\visual studio 2010\projects\cppalgo\recudef\test1.h 9 1 RecuDef

  3. error C4430: missing type specifier - int assumed. Note: C++ does not support default-int c:\users\xingyo\documents\visual studio 2010\projects\cppalgo\recudef\test1.h 9 1 RecuDef


This is not possible verbatim in C++. The explanation is that the compiler needs full, not just forward, declaration of a class to be able to use it as a member of another class. It simply needs the size of a class object.

The workaround in C++ (and in C) is to use a pointer or a reference as a member of one of the classes. That way you can use forward declaration as follows:

class A; // forward declaration

class B {
    // ...
    A* pa;
};

class A { // full declaration
    // ...
    B b;
};

It's your (not the compiler or runtime) responsibility to keep the instance of A that instance of B points to (or references) valid.


You can't solve it. It's meaningless. You've defined A to contain B which contains another A which contains another B which ... You can't possibly have intended that. Maybe you need to use a pointer or a reference?


Split you codes into 4 files, say A.h, A.cpp, B.h, and B.cpp.

// A.h

class B;
class A {
public:
    A();
    B* b;
};

// A.cpp

#include "A.h"
#include "B.h"

A::A() : b(new B) {
}

// B.h

class A;
class B {
public:
    B(A* a_);
    A* a;
};

// B.cpp

#include "B.h"
#include "A.h"

B::B(A* a_) : a(a_) {
}

And use them this way:

#include "A.h"
#include "B.h"

int main() {
    A a;
    B b(&a);

    // do logics

    return 0;
}


If it is a recursive problem. Declare the classes without the definitions:

class A;
class B;

class A
{
   ...
};

class B
{
   ...
};

See: http://www.gotw.ca/gotw/034.htm


You cannot have a recursive definition like that in C++. Before you can declare an object of class A, A must be fully defined, so that the sizeof(A) is known to the compiler. Same with B. However, you can get around it by using pointers. You can declare a pointer to an object of class A by simply "promising" to define class A at some later point. This is called forward declaration.

class B;  // forward declaration

class A
{
  B *b;
};

class B
{
  A *a;
};

Forward declarations also work for references.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜