C++类的交叉引用
对于C++中,两个类中相互引用对方,当然只能是在指针的基础上,于是我们知道。也就是说在A类的有一个指针引用B类的成员函数或成员对象,而B类中又有一个指针来访问A中的成员函数或对象。这就是C++中类的交叉引用编译于。那如何解决这个问题呢?
当然方法很多,但是我一般采用的方法就是声明与实现的分离。
也就是说类中的成员函数我们只在类中声明,然后函数的实现要放到另一个文件中去。
主要是在类中的交叉引用时候,存在一个谁先谁后的问题,也就是说假如A类中用B的指针引用了B的一个成员函数,如果B中没有引用A的成员,那问题好办,我们先在A类的头文件中引用B的头文件,于是我们保证先编译B,然后再编译A。
但是我们如果在B中也有一个A的指针引用了A的成员函数呢?
那么是先编译A还是先编译B呢? 如果先编译A,那么A中引用了B的成员函数,B还没编译呢! 如果先编译B,而B中又引用了A的成员函数呢!
这样就想当于死锁或者不停地迭代。那么如何解决呢?
方法就是先声明,再定义。直接看我们的解决方法:
当然方法很多,但是我一般采用的方法就是声明与实现的分离。
也就是说类中的成员函数我们只在类中声明,然后函数的实现要放到另一个文件中去。
主要是在类中的交叉引用时候,存在一个谁先谁后的问题,也就是说假如A类中用B的指针引用了B的一个成员函数,如果B中没有引用A的成员,那问题好办,我们先在A类的头文件中引用B的头文件,于是我们保证先编译B,然后再编译A。
但是我们如果在B中也有一个A的指针引用了A的成员函数呢?
那么是先编译A还是先编译B呢? 如果先编译A,那么A中引用了B的成员函数,B还没编译呢! 如果先编译B,而B中又引用了A的成员函数呢!
这样就想当于死锁或者不停地迭代。那么如何解决呢?
方法就是先声明,再定义。直接看我们的解决方法:
class Observer(Observer.h)
#ifndef OBASER_H
#define OBASER_H
#include"Observerable.h"
class Observerable;
class Observer{
private:
Observerable *subject_;
public:
virtual void update(){};
void observer(Observerable *s);
~Observer();
};
#endif
#ifndef OBASERVERABLE_H
#define OBASERVERABLE_H
#include<iostream>
#include<vector>
#include<algorithm>
class Observer;
class Observerable{
private:
std::vector<Observer*> obsPtrs;
public:
void register_obs(Observer *obs_);
void unregister_obs(Observer *obs);
void notificate_obs();
};
#endif
我们可以看到在两个类中,对对方都加了一次声明如:
class Observer
class Observerable
这里我们只是告诉编译器,我们有这么一个类存在,不是一般的错误或者什么重定义乱定义之类的。
然后在另两个文件中加类的成员函数的实现代码:
class Observer
class Observerable
这里我们只是告诉编译器,我们有这么一个类存在,不是一般的错误或者什么重定义乱定义之类的。
然后在另两个文件中加类的成员函数的实现代码:
#include"Observer.h"
#include"Observerable.h"
void Observer::observer(Observerable *s){
s->register_obs(this);
}
Observer::~Observer(){
subject_->unregister_obs(this);
}
#include"Observerable.h"
#include"Observer.h"
void Observerable::notificate_obs(){
for(int i=0;i<obsPtrs.size(); i++){
if(obsPtrs[i]){
obsPtrs[i]->update();
}
}
}
void Observerable::register_obs(Observer *obs_){
obsPtrs.push_back(obs_);
}
void Observerable::unregister_obs(Observer *obs){
std::vector<Observer*>::iterator obsIter;
if((obsIter=std::find(obsPtrs.begin(),obsPtrs.end(),obs))!=obsPtrs.end()){
obsPtrs.erase(obsIter);
}
}
而且在两个具体实现的文件中如Observerable.cpp和Observer.cpp中,我们都分别引用了对方的头文件,这回我们就得知道对方类的
成员函数有哪些了,以及其函数接口。
成员函数有哪些了,以及其函数接口。