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中,我們都分別引用了對方的頭文件,這回我們就得知道對方類的
成員函數有哪些了,以及其函數接口。










免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM