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的成员函数呢!
这样就想当于死锁或者不停地迭代。那么如何解决呢?
方法就是先声明,再定义。直接看我们的解决方法:

class Observer(Observer.h)

  1. #ifndef OBASER_H
  2. #define OBASER_H
  3. #include"Observerable.h"
  4. class Observerable;
  5. class Observer{
  6. private:
  7.    Observerable *subject_;
  8. public:
  9.    virtual void update(){};
  10.    void observer(Observerable *s);
  11.    ~Observer();
  12. };
  13. #endif
  1. #ifndef OBASERVERABLE_H
  2. #define OBASERVERABLE_H
  3. #include<iostream>
  4. #include<vector>
  5. #include<algorithm>
  6. class Observer;
  7. class Observerable{
  8. private:
  9.    std::vector<Observer*> obsPtrs;
  10. public:
  11.    void register_obs(Observer *obs_);
  12.    void unregister_obs(Observer *obs);
  13.    void notificate_obs();
  14. };
  15. #endif
我们可以看到在两个类中,对对方都加了一次声明如:
class Observer
class Observerable
这里我们只是告诉编译器,我们有这么一个类存在,不是一般的错误或者什么重定义乱定义之类的。
然后在另两个文件中加类的成员函数的实现代码:

  1. #include"Observer.h"
  2. #include"Observerable.h"
  3. void Observer::observer(Observerable *s){
  4.    s->register_obs(this);
  5. }
  6. Observer::~Observer(){
  7.    subject_->unregister_obs(this);
  8. }
  1. #include"Observerable.h"
  2. #include"Observer.h"
  3. void Observerable::notificate_obs(){
  4.    for(int i=0;i<obsPtrs.size(); i++){
  5.        if(obsPtrs[i]){
  6.            obsPtrs[i]->update();
  7.        }
  8.     }
  9. }
  10. void Observerable::register_obs(Observer *obs_){
  11.        obsPtrs.push_back(obs_);
  12.    }
  13. void Observerable::unregister_obs(Observer *obs){
  14.    std::vector<Observer*>::iterator obsIter;
  15.    if((obsIter=std::find(obsPtrs.begin(),obsPtrs.end(),obs))!=obsPtrs.end()){
  16.        obsPtrs.erase(obsIter);
  17.    }
  18. }
而且在两个具体实现的文件中如Observerable.cpp和Observer.cpp中,我们都分别引用了对方的头文件,这回我们就得知道对方类的
成员函数有哪些了,以及其函数接口。









posted @ 2015-07-21 14:19  yml435  阅读(4360)  评论(0编辑  收藏  举报