在类之间共享信息

Sharing info between classes

本文关键字:信息 共享 之间      更新时间:2023-10-16

我正在尝试使用这里的信息在类之间共享信息,除了我不能得到这两个类的编译,从而到相互沟通。

所以,我想让ClassB得到对ClassA的引用,并且ClassBClassA中初始化

编译错误(使用c++):

In member function 'void ClassA::foo()':
hello.cpp:9: error: 'ClassB'未在此作用域中声明
hello.cpp:9: error: 'someB'未在此范围内声明
hello.cpp:9:错误:期望类型说明符在'ClassB'之前
hello.cpp:9: error: expected ';' before 'ClassB'

然后我尝试在ClassA之前添加class ClassB;

:

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的前向声明
hello.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();
        }
};

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

你应该做的是把你的代码分成声明(头)和实现。

a.h

// 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);
}

b.h

// 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
}

喜欢这个问题每个类(A和B)都应该有一个头文件和一个实现文件。

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

每个CPP文件(例如a.p p)可以包含多个头文件(例如A.h和B.h)。建议每个CPP文件首先包含自己的头文件(例如a.p应该先包含A.h,然后是B.h,而b.p应该先包含B.h,然后是A.h)。

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

例如:

//a.hB类;//前向声明

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
}

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

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