如何在C ++中创建两个使用彼此作为数据的类?

时间:2011-02-11 00:50:49

标签: c++ class pointers header-files

我正在寻找创建两个类,每个类都包含另一个类类型的对象。我怎样才能做到这一点?如果我不能这样做,是否有解决办法,比如每个类包含一个指针到另一个类类型?谢谢!

这就是我所拥有的:

文件: bar.h

#ifndef BAR_H
#define BAR_H
#include "foo.h"
class bar {
public:
  foo getFoo();
protected:
  foo f;
};
#endif

文件: foo.h

#ifndef FOO_H
#define FOO_H
#include "bar.h"
class foo {
public:
  bar getBar();
protected:
  bar b;
};
#endif

文件: main.cpp

#include "foo.h"
#include "bar.h"

int
main (int argc, char **argv)
{
  foo myFoo;
  bar myBar;
}

$ g ++ main.cpp

In file included from foo.h:3,
                 from main.cpp:1:
bar.h:6: error: ‘foo’ does not name a type
bar.h:8: error: ‘foo’ does not name a type

3 个答案:

答案 0 :(得分:92)

你不能让两个类直接包含另一个类型的对象,因为否则你需要为对象提供无限空间(因为foo有一个带有foo的条形条等等。)

但是,您可以通过让两个类存储指向彼此的指针来实现此目的。为此,您需要使用前向声明,以便两个类知道彼此的存在:

#ifndef BAR_H
#define BAR_H

class foo; // Say foo exists without defining it.

class bar {
public:
  foo* getFoo();
protected:
  foo* f;
};
#endif 

#ifndef FOO_H
#define FOO_H

class bar; // Say bar exists without defining it.

class foo {
public:
  bar* getBar();
protected:
  bar* f;
};
#endif 

请注意,两个标头不相互包含。相反,他们只是通过前向声明知道其他类的存在。然后,在这两个类的.cpp文件中,您可以#include另一个标头来获取有关该类的完整信息。这些前向声明允许您打破“foo needs bar needs foo needs bar”的参考周期。

答案 1 :(得分:4)

这没有意义。如果A包含B,而B包含A,则它将是无限大小。想象一下,放两个盒子并试图将两者放在一起。不行,对吗?

指针虽然有效:

#ifndef FOO_H
#define FOO_H

// Forward declaration so the compiler knows what bar is
class bar;

class foo {
public:
  bar *getBar();
protected:
  bar *b;
};
#endif

答案 2 :(得分:-2)

对,所以只需添加

上述方法仅允许您具有指向所述类的指针。

在旅行中,我发现创建一个具有指向它的指针的类的实例的函数也可以完成(代码图像,最后是实际代码)

code and running

这里包含了您正在“生成”的类的标题,以便编译器具有有关它的实际信息,因此可以创建它。

当然,这还允许您在A (代码图像,末尾的实际代码)中包含B的实例

b inside of a kappa

您可能还可以想到其他一些海螺的东西,gn。


非图片代码

示例1

a.h

#pragma once

#include "b.h"

struct A {
    char aye, beye, ceye;
    B createB(unsigned val);
};

a.cpp

#include "a.h"

B A::createB(unsigned val){
    return {69, this};
}

b.h

#pragma once

struct A;

struct B {
    unsigned ellel;
    A* dad;
    B& printOurEllel();
};

b.cpp

#include <stdio.h>
#include "b.h"

B& B::printOurEllel(){
    printf("ellel: %d\n", this->ellel);
    return *this;
}

主要

#include <stdio.h>

#include "a.h"
#include "b.h"


int main() {
    A elgay = { 1, 2, 3 };
    printf("%d\n", elgay.createB(69).printOurEllel().dad->beye);
    getchar();
}

结果

ellel: 69
2

示例2

a.h

#pragma once

#include "b.h"

struct A {
    char aye, beye, ceye;
    B yeetos;
};

b.h

#pragma once

struct A;

struct B {
    unsigned ellel;
    A* dad;
    B& printOurEllel();
};

b.cpp

#include <stdio.h>
#include "b.h"

B& B::printOurEllel(){
    printf("ellel: %d\n", this->ellel);
    return *this;
}  

主要

#include <stdio.h>

#include "a.h"
#include "b.h"


int main() {
    A elgay = { 1, 2, 3, {69, &elgay} };
    printf("%d\n", elgay.yeetos.printOurEllel().dad->beye);
    getchar();
}

结果

ellel: 69
2