刚开始编程的时候,我相信大家都跟我一样,是这样把两个类联系起来的(现用类A和类B举例):
class A
{
private:
B *b;
}
这样,当a需要的时候可以调用B类的函数方法
这样的缺点是:
1:A可以使用B的方法,B不可以使用A的方法(B看不到A);
2:内聚性弱,也就是a对象消失b对象一定消失(想像一下a,b是两个窗口,a是登陆,b是主页,当点击a上的按钮时生成b,但a界面不能消失释放,但实际情况下登陆成功后登陆界面消失),b对象生成失败a对象也就失败。
3:如果三个类,四个类,五个类之间交流,互相交流,但上述方法不可能实现
这个问题一直困扰了我很久,上述简单处理虽然可以解决一些基本的问题,但事实上两个类是如何通信 的呢?
其实方法有很多,大体思路是这样的:
定义一个类M,在M中让A和B作为其成员变量,(这样M中的函数就可以调用A,B中的函数方法),当A中想要发消息给B时,想方设法把消息给M,M再调用B中的函数传给B,那么这个"想方设法"是什么方法呢?
开始我是这么想的
M::M()
{
a=new A(this);//把当前的this指针传给a,这样在a的函数里就可以调用M的函数了。
}
编译会发生错误
为 什么捏? 是这样滴:在写类M的时候,要包含头文件#include“A.h”有木有!!,在写类A的函数的时候要包含头文件#include"M.h"有木有!! (因为在A的构造里要定义一个M类型的指针做实参啊!),这里就有问题,计算机执行时,1:走到#include“A.h”这一行代码时要先看看A.h里 有什么。2:走到A.h里的时候,发现有#include"M.h"这行代码,然后又进入M.h看看,3:执行1步骤。。。。。是不是循环,无限循环有木 有!!!所以报错。
解决方法有很多,例如监听A的函数,利用函数指针,利用全局函数(全局函数简单好用,但破坏了面向对象的封装性)
好了,不罗嗦了,正确答案如下:
用接口函数,interface,在c++下没有定义接口函数,其实接口函数就是纯虚函数,在vc下(别的我不知道行不行)可以这样:
#include
using namespace std;
#define interface class __declspec(novtable)
interface InterFace
{
virtual void f();
};
为了解决那个让计算机迷糊的问题,我们让M继承InterFace,然后传参的时候传InterFace类型的,这样就不会重复包含了,试试:
#include"Interface.h"
#include"A.h"
#include"B.h"
class M :public InterFace
{
private:
A *a;
B *b;
public:
M()//构造
{
a=new A(this);//因为M继承InterFace所以可以用父类的指针来作为它的实参!
b=new B();
}
void f()
{
b->show();//调用B类方法
}
};
在A类:
#include"InterFace.h"
class A
{
public:
A(InterFace *i)
{
printf("A要调用M中的f()函数,让f()函数调用B的函数,这样A就成功通信到了B!");
i->f();//这里调用的是InterFace的f函数,不过在M类中实例化了
}
};
在B类:
#include"stdio.h"
class B
{
public:
void show()
{
printf("我被M调用了!");
}
};
int mian()
{
M m;
return 0;
}