在B类中使用类A的向量

时间:2012-11-04 22:06:48

标签: c++ class vector

我创建了一个A类和一个B类,我试图在A中设置一个B类型的矢量,在B中设置一个A类矢量:

A类标题:

#ifndef A_H_
#define A_H_

#include "B.h"
#include <vector>
using namespace std;
class A {

public:
    vector<B> bvector; // here is the error
    A();
};

#endif /* A_H_ */

B类标题:

#ifndef B_H_
#define B_H_
#include "A.h"
#include <vector>

using namespace std;

class B {
vector<A> aVector; //Here is the error

public:
    B();
};

#endif /* B_H_ */

但我收到以下错误:

  

“.. \ src / B.h:16:8:错误:'A'未在此范围内声明

     

.. \ src / B.h:16:9:错误:模板参数1无效

     

.. \ src / B.h:16:9:错误:模板参数2无效“

如果我删除了B中的坏行,会转到A.h。我做错了什么?

3 个答案:

答案 0 :(得分:2)

  

我创建了一个A类和一个B类,我试图设置一个类型的向量   A中的B和B中的A型矢量

您正在课程之间创建circular dependency。这通常是一件坏事,特别是在C ++中。

为了编译A,编译器需要知道B的定义(#include“B.h”)。不幸的是,B头包含对A类的引用(这里是循环引用)。 编译器无法处理这种情况,因为A头已包含在当前TU中(请参阅包含警卫)。

尽管经常有循环引用是一个糟糕设计的症状,但最终你可以使用前向声明克服这个问题。 例如,您可以这样修改B:

#ifndef B_H_
#define B_H_

#include <vector>

using namespace std;
class A; //forward declaration of class A
class B {
vector<A*> aVector; //note that you must only use pointer to A now 

public:
    B();
};

#endif /* B_H_ */

使用转发声明基本上告诉编译器将在其他地方定义类型A.编译器可以依赖于这个事实,但它对A没有任何了解(特别是它忽略了A及其方法的大小)。 所以在B中,如果你有前向声明的A,你只能使用指向A类的指针(指针总是大小相同),你不能从B里面调用A类的任何方法。

答案 1 :(得分:1)

这里的诀窍是你需要转发声明两个类中的一个。不幸的是,前向声明不允许你在标题中使用完整类型 - 它们只允许你使用指向该类型的指针。所以,即便如此,在这种情况下也行不通。

您可以使用 PIMPL惯用法(指向IMPLementation的指针)(google that)来规避此问题。

PIMPL习惯用法基本上可以创建第三种类型。然后你的类型B将保存一个指向包含你的类型为A的向量的实现类的指针。应该保存在B中的向量的所有操作都将被转发到实际持有向量A的新实现类。 / p>

例如:

//Forward declare impl class.
class BImpl;

class B {
    private:
        BImpl* impl;

    public:
        void PrintVector() { impl->PrintVector(); }
};

class A {
    private:
        std::vector<B> vec;

    public:
        void PrintVector() { /* Do printing */ }
};

class BImpl {
    private:
        std::vector<A> vec;

    public:
        void PrintVector() { /* Do Printing */ }
};

我没有为这些类包含构造函数或种群方法,但是你应该得到一般的想法:)

答案 2 :(得分:0)

你有一个循环依赖。

A.h包含B.h,其中包含A.h,但已定义A_H_后卫,因此会跳过A.h的内容,因此B.h的内容已处理{1}},其引用A但尚未定义,因为您尚未处理A.h中的任何内容,但顶部的#define#include指令除外A.h