程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> C++沉思錄讀書筆記(5章)-代理類

C++沉思錄讀書筆記(5章)-代理類

編輯:C++入門知識

 

問題描述:如何設計一個容器,能使得它能包含類型不同但是彼此相關的對象?

問題描述:如何復制編譯時類型未知的對象?

 

解決方案一:使用容器存儲指向對象的指針,通過繼承來處理類型不同的對象。

這個方案有嚴重的問題:

       問題一:無法讓容器中的指針指向一個局部變量,例如:

 

Vehicle * parking_lot[1000]; 

Automobile x = /*..*/ 

Parking_lot[num_vehicles++] = &x; 

       一旦x不存在了,Parking_lot就不知道指向哪裡了。

       我們可以變通一下,讓放入Parking_lot的值,指向原來對象的副本,而不直接存放原來對象的地址,例如:

       Parking_lot[num_vehicles++]= new Automobile(x);

       這個改進方案又帶來一個問題,那就是我們必須知道x的靜態類型。假如我們想讓parking_lot[p]指向的Vehicle的類型和值與parking_lot[q]指向的對象相同,那在我們無法得知parking_lot[q]的靜態類型的情況下,我們無法做到這點。

 

解決方案二(方案一的改進):增加虛擬復制函數來復制編譯時類型未知的對象,代碼描述如下

 

class Vehicle 

    public: 

        virtual Vehicle * copy() const = 0; 

    /**/ 

};//Vehicle的派生類都自實現copy函數 

class Truck : public RoadVehicle 

public: 

        Vehicle* copy() const { return new Truck(*this); } 

    /**/ 

}; 

       假如我們想讓parking_lot[p]指向的Vehicle的類型和值與parking_lot[q]指向的對象相同,可以簡單是使用如下代碼:parking_lot[p] =parking_lot[q].copy();

 

解決方案三(與方案二作用類似,但實現手段有不同):使用代理類

       代理類:行為與原類相似,又潛在的表示了所有繼承自原類的類

       Vehicle類的代理類VehicleSurrogate的描述如下:

 

class VehicleSurrogate 

public: 

    VehicleSurrogate() : vp(NULL) {}; 

    VehicleSurrogate(const Vehicle& v) : vp(v.copy()) {}; 

    ~VehicleSurrogate() {}; 

    VehicleSurrogate(const VehicleSurrogate& v) : vp(v.vp ? v.vp->copy() : NULL) {}; //v.vp非零檢測 

    VehicleSurrogate& operator=(const VehicleSurrogate& v)  

    { 

        if (this != &v) // 確保沒有將代理賦值給它自身 

        { 

            delete vp; 

            vp = (v.vp ? v.vp->copy() : NULL); 

        } 

 

        return *this; 

    }; 

 

    //來自類Vehicle的操作 

    void start() 

    { 

        if (vp == 0) 

            throw "empty VehicleSurrogate.start()"; 

 

        vp->start(); 

    }; 

 

private: 

    Vehicle* vp; 

}; 

   完成了這些工作後,就很容易定義我們所需要的操作了,如下:

 

VehicleSurrogate  parking_lot[1000]; 

Automobile x = /*..*/ 

Parking_lot[num_vehicles++] = x; 

//Parking_lot[num_vehicles++] = VehicleSurrogate(x);//此語句與上條語句作用一致 

/*...*/ 

Parking_lot[p] = Parking_lot[q]; 

 

作者 yucan1001

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved