我正在尝试使用来自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();
}
};
答案 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文件中的头文件和方法定义中拆分类和方法声明来打破此圈。