How to create two classes in C++ which use each other as data?

谁都会走 提交于 2019-12-27 16:47:11

问题


I'm looking to create two classes, each of which contains an object of the other class type. How can I do this? If I can't do this, is there a work-around, like having each class contain a pointer to the other class type? Thanks!

Here's what I have:

File: bar.h

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

File: foo.h

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

File: 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

回答1:


You cannot have two classes directly contain objects of the other type, since otherwise you'd need infinite space for the object (since foo has a bar that has a foo that has a bar that etc.)

You can indeed do this by having the two classes store pointers to one another, though. To do this, you'll need to use forward declarations so that the two classes know of each other's existence:

#ifndef BAR_H
#define BAR_H

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

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

and

#ifndef FOO_H
#define FOO_H

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

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

Notice that the two headers don't include each other. Instead, they just know of the existence of the other class via the forward declarations. Then, in the .cpp files for these two classes, you can #include the other header to get the full information about the class. These forward declarations allow you to break the reference cycle of "foo needs bar needs foo needs bar."




回答2:


That doesn't make sense. If A contains B, and B contains A, it would be infinite size. Imagine putting having two boxes and trying to put both into each other. Doesn't work, right?

Pointers work though:

#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



回答3:


Right so just to add,

the above methods will only allow you to have pointers to said classes.

In my travels I've found that a function that creates an instance of a class that has a pointer to it can also be done (code image, actual code at the end):

Here you include the header from the class you're "spawning", so that the compiler has actual information about it and can thus create it.

Of course this also allows you to have an instance of B inside of A (code image, actual code at the end):

You can probably also think of some other kewl stuff, gn.


Non-image Code

Example 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;
}

main:

#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();
}

result:

ellel: 69
2

Example 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;
}  

main:

#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();
}

result:

ellel: 69
2


来源:https://stackoverflow.com/questions/4964482/how-to-create-two-classes-in-c-which-use-each-other-as-data

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!