在类之间共享信息

时间:2012-12-29 16:40:07

标签: c++ object

我正在尝试使用来自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'

然后我尝试在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'的前向声明   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();
        }
};

3 个答案:

答案 0 :(得分:3)

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

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

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
}

答案 1 :(得分:1)

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

每个头文件(例如Ah)不应该包含其他头文件(例如Bh),但可以包括对另一个类的前向引用(例如类似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
}

答案 2 :(得分:0)

class A需要class B的完整定义才能创建并调用someB->setRelative(this)class B需要class A的完整定义才能致电m_relative->bar()。 所以这有点鸡和鸡蛋的问题。

您只能通过在cpp文件中的头文件和方法定义中拆分类和方法声明来打破此圈。