【问题标题】:Sharing info between classes在班级之间共享信息
【发布时间】:2012-12-29 16:40:06
【问题描述】:

我正在尝试使用来自here 的信息在班级之间共享信息, 除了我无法编译这两个类,因此 相互交流。

所以,我想要ClassB 获得对ClassA 的引用,并且 ClassB 将在 ClassA 中初始化。

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

在成员函数'void ClassA::foo()':
hello.cpp:9: 错误:'ClassB' 未在此范围内声明
hello.cpp:9: 错误:'someB' 未在此范围内声明
hello.cpp:9:错误:'ClassB' 之前的预期类型说明符
hello.cpp:9: 错误:在'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();
        }
};

【问题讨论】:

  • 请查一下继承这个词。您可能会发现它很有用。
  • 这里不能使用继承,因为我在处理对象,一个实例化类的引用,所以我不能继承对象引用。
  • 构造函数在哪里?

标签: c++ object


【解决方案1】:

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

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

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
}

【讨论】:

    【解决方案2】:

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

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

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

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

    例如:

    // a.h 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
    }
    

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-09-15
        • 2018-11-22
        • 1970-01-01
        • 2016-07-22
        • 1970-01-01
        相关资源
        最近更新 更多