指針支持隱式轉換(implicit conversion), 在動態綁定中,派生類指針可以轉換為基類指針.
但是模板的實例化(instantiations)之間, 是單獨存在的,
派生類的實例化的模板(SmartPtr<Derived>), 不能轉換為基類實例化的模板(SmartPtr<Base>);
需要明確的編寫, 因為派生類也可以繼續做為基類, 產生派生類, 所以無法直接寫出構造函數.
使用成員函數模板(member function template), 再聲明一個模板參數, 提供這種隱式轉換.
為了使用轉換只能發生在可以轉換的指針, 如"Derived->Base", 不能逆序, 所以引入相關約束判斷是否可以轉換.
在成員初始化列表(member initialization list)中調用get()函數, 判斷是否可以隱式轉換.
使用成員函數模板的構造函數, 是成員函數的一種, 並不是重載復制構造函數, 所以類會自動生成一個默認構造函數.
代碼注意: 第一個可以轉換, 第二個不能轉換, 第三個使用默認的構造函數.
代碼:
/* * test.cpp * * Created on: 2014.04.20 * Author: Spike */ /*eclipse cdt, gcc 4.8.1*/ #include <iostream> using namespace std; class Base{}; class Derived : public Base {}; template<typename T> class SmartPtr { public: SmartPtr() = default; template<typename U> SmartPtr(const SmartPtr<U>& other) : heldPtr(other.get()) { std::cout << "SmartPtr:CopyConstructor" << std::endl; } T* get() const {return heldPtr;} private: T* heldPtr; }; int main() { SmartPtr<Derived> spd; SmartPtr<Base> spb(spd); //SmartPtr<Base> spb1; //SmartPtr<Derived> spd1(spb1); //無法進行隱身轉換 SmartPtr<Base> spd2; SmartPtr<Base> spd21(spd2); //使用默認的復制構造函數 return 0; }
輸出:
SmartPtr:CopyConstructor
作者:csdn博客 Spike_King