怎么消除类的循环依赖?高手看过来。

collide 2004-03-20 01:58:50
据个例子来说:
class A;
class AA;
class B;

class A
{
public:
virtual void dosomething() {...}

}

class AA : public A
{
public:
doita(B& b) {
b.dosomething();
...
}
}

class B
{
pubic:
doitb(AA& a)
{
a.dosomething();

}
void dosomething() {...}
}
...全文
215 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
nickadams 2004-03-20
  • 打赏
  • 举报
回复
道理很简单,但要说清楚又不太容易。
C++编译器在编译你的代码的时候是按顺序来的。当它编译到AA类时,还不知道B类是什么样子,有些什么接口,所以在AA里调用b.dosomething()会报错。(你把B和AA调个位置也又会报a.dosomething()的错)。
B类的前向声明只是告诉编译器有这么个类型存在,这样你可以在定义AA类时,使用B的指针或引用作为参数或返回值,但你不能在AA类里实例化B,或访问B的成员。

解决办法就是你已经使用的办法,把B和AA的定义放到头文件中。也可以在同一个文件中,但B和AA的定义必须在它们的实现代码的前面,就象辣子鸡丁的代码那样。这样编译器编译头文件(或者该文件的前面部分)时已经得到了B和AA的成员结构,知道B类有个dosomething函数,就不会报错了。

Java和C#就没有这个问题。我想可能是编译器先扫描一遍所有class的接口,然后再来编译函数吧。
Jinhao 2004-03-20
  • 打赏
  • 举报
回复
那些comment都是 //注意返回值
Jinhao 2004-03-20
  • 打赏
  • 举报
回复
应该这样,不好意思,先放错了
class B;

class A
{
public:
virtual void dosomething(){}

};

class AA : public A
{
public:
void doita(B& b); //·µ»ØÖµ
};

class B
{
public:
void doitb(AA& a) //·µ»ØÖµ
{
a.dosomething();

}
void dosomething() {}
};

void AA::doita(B& b) { //·µ»ØÖµ
b.dosomething();
}
collide 2004-03-20
  • 打赏
  • 举报
回复
可是还是不行啊,不过我已经自己解决了,我把类的成员函数的实现放在另一个文件中,而不是在类声明中实现,所以已经没有问题了。不过为什么嵌入在类声明中实现,就不行能,我还是不知道是什么原因
Jinhao 2004-03-20
  • 打赏
  • 举报
回复
或者这样声明,举个例子

class A; //声明

class B{ //声明
public:
void fun(A&); //A的引用作参数,所以只需要编译器知道有class A的存在,故上面只用了class A;这样的生命
};

class A{
public:
void fun(B& b){
b.fun(*this); //在这之前都没见class B的定义,而又在这里调用了B的成员,所以编译器需要关于class B的更多信息,故再上面需要对class B的成员进行声明
}
void fun22(){
cout<<"AAAA"<<endl;
}
};

void B::fun(A& a){ //这是对class B这个成员的定义
cout<<"BBBB"<<endl;
a.fun22();
}

int main(){
A a;
}
Jinhao 2004-03-20
  • 打赏
  • 举报
回复
应该这样放置
class A
{
public:
virtual void dosomething() {...}

};

class B
{
pubic:
doitb(AA& a)
{
a.dosomething();

}
void dosomething() {...}
};


class AA : public A
{
public:
doita(B& b) {
b.dosomething();
...
}
};
因为你那样声明只是告诉编译器有这样的class存在,而并没有告诉它这些类的细节,所以你也应该对类中成员函数进行声明
collide 2004-03-20
  • 打赏
  • 举报
回复
我知道是因为类的循环依赖,不过我已经进行了类的前向声明,为什么编译还是不行,我是在VC6.0中编译的。
望高手执教。

64,654

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧