1

我正在尝试使用此处的信息在类之间共享信息,但我无法让这两个类编译并因此相互通信。

所以,我想要的是ClassB获得对 的引用ClassA,并 ClassBClassA.

编译器错误(使用 g++):

在成员函数中'void ClassA::foo()'
hello.cpp:9:错误:'ClassB'未在此范围内声明
hello.cpp:9:错误:'someB'未在此范围内声明hello.cpp:9:错误: hello.cpp:9
之前的预期类型说明符'ClassB'
: 错误:';'之前预期'ClassB'

所以我尝试class ClassB;在之前添加ClassA

喜欢:

class ClassB; // just this here.

class ClassA; // all of classA here.

class ClassB; // all of classB here.

我得到:

hello.cpp:在成员函数'void ClassA::foo()'中:
hello.cpp:11:错误:无效使用不完整类型'struct ClassB'
hello.cpp:3:错误:'struct ClassB'的前向声明
你好.cpp:12:错误:不完整类型“struct ClassB”的无效使用
hello.cpp:3:错误:“struct ClassB”的前向声明


这是我根据上面的网站尝试使用的代码:

include stdio.h

class ClassA {
    public:
        void foo() {
            ClassB *someB = new ClassB();
            someB->setRelative(this);
        }

        void bar() {
            printf("B is communicating with me =)\n");
        }
};

class ClassB {

    ClassA *m_relative;

    public:
        void setRelative(ClassA *other) {
            this->m_relative = other;
        }

        void foo() {
            m_relative->bar();
        }
};
4

3 回答 3

3

你显然在这里有一个循环依赖,你不能仅仅使用标题来解决这个问题(可能有一些宏技巧,但我不会担心)。

您应该做的是将代码拆分为声明(标头)和实现。

// only include this file once per translation unit
#pragma once

// tell the compiler B is going to be a class,
// so B* is a pointer to a class - nothing more is needed for now.
class B;

// full declaration of A
class A {
    B *child;

public:
    A(void);
}

a.cpp

#include "a.h" // included whenever the structure/size of A has to be known
#include "b.h" // same for B

A::A(void) : child(new B(this)) {
    // do something with child or...
    B * = new B(this);
}

bh

// only include this file once per translation unit
#pragma once

// again, just tell the compiler A is going to be a class
class A;

class B {
    A *parent;
public:
    B(A *pparent);
}

b.cpp

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

B::B(A *pparent) : parent(pparent) {
    // do something with parent
}
于 2012-12-29T16:56:54.130 回答
1

Like This question 每个类(A 和 B)都应该有一个头文件和一个实现文件。

每个头文件(例如 Ah)不应包含另一个头文件(例如 Bh),但可以包含对另一个类的前向引用(例如,像 B 类的语句;),然后可以使用指针和/或对另一个的引用在其声明中的类(例如,类 A 可能包含 B* 作为数据成员和/或作为方法参数)。

每个 CPP 文件(例如 A.cpp)可能包括一个以上的头文件(例如 Ah 和 Bh)。建议每个 CPP 文件应首先包含其自己的头文件(例如 A.cpp 应包含 Ah 然后 Bh,而 B.cpp 应包含 Bh 然后 Ah)。

每个头文件应该只包含声明,而不是类的定义:例如,它将列出类方法的签名,但不列出方法体/实现(方法体/实现将在 .cpp 文件中,不在头文件中)。由于头文件不包含实现细节,因此它们不依赖(不需要查看)其他类的细节;最多他们需要知道,例如,B 是一个类的名称:它可以从前向声明中获得,而不是通过在另一个头文件中包含一个头文件。

例如:

//啊B类; // 前向声明

lass A {
   void foo(B* b); // pointers and references to forward-declared classes are ok
};


// b.h
Class A; // forward declaration

Class B {
   void bar(A& a); // pointers and references to forward-declared classes are ok
};


// a.cpp
#include "a.h"
#include "b.h"

void A::foo(B* b) {
   b->bar(*this); // full declaration of B visible, ok to call members now
}


// b.cpp
#include "a.h"
#include "b.h"

void B::bar(A& a) {
   a.foo(this); // full declaration of A visible, ok to call members now
}
于 2012-12-29T16:56:34.057 回答
0

class A需要一个完整的定义class B才能创建它并调用someB->setRelative(this). class B需要完整的定义class A才能调用m_relative->bar()。所以这是一个先有鸡还是先有蛋的问题。

您只能通过拆分头文件中的类和方法声明以及 cpp 文件中的方法定义来打破这个循环。

于 2012-12-29T17:01:39.937 回答