![](/img/trans.png)
[英]Compilation Error on passing smart pointer to a template class member function
[英]my own smart pointer template compilation error
我正在遵循斯科特·邁耶斯書中的簡單程序。 我正在使用Visual Studio 2009進行編譯。
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
class Top { };
class Middle: public Top { };
class Bottom: public Middle { };
template<typename T>
class SmartPtr {
public:
template<typename U>
SmartPtr(const SmartPtr<U>& other) : heldPtr(other.get()) { }
T* get() const { return heldPtr; }
private:
// built-in pointer held
T *heldPtr;
};
int main()
{
SmartPtr<Top> pt1 = SmartPtr<Middle>(new Middle); // SmartPtr<Top>
}
在編譯期間我遇到以下錯誤
1>d:\technical\c++study\addressconv.cpp(36) : error C2440: '<function-style-cast>' : cannot convert from 'Middle *' to 'SmartPtr<T>'
1> with
1> [
1> T=Middle
1> ]
1> No constructor could take the source type, or constructor overload resolution was ambiguous
1>d:\technical\c++study\readparsing\readparsing\addressconv.cpp(36) : error C2512: 'SmartPtr<T>' : no appropriate default constructor available
1> with
1> [
1> T=Top
1> ]
請請求幫助解決問題。 問題的根本原因是什么?
謝謝!
您需要實現一個接受U*
的構造函數。 抱怨不能將U*
明確轉換為SmartPtr<U>
。
SmartPtr<Top> pt1 = SmartPtr<Middle>(new Middle()); // SmartPtr<Top>
^^
首先,創建兩個副本構造函數。 一個接受相同類型,另一個接受可以動態轉換為基本類型的任何其他類型。 這就是我的意思。
template<typename T>
class SmartPointer
{
// No dynamic_cast and hence no overhead
SmartPointer(const SmartPointer<T>& other):heldPtr(other.heldPtr){}
// Has dynamic_cast'ing
template<typename U>
SmartPointer(const SmartPointer<U>& other):heldPtr(dynamic_cast<T*>(other.get())){}
// Rest of the code
}
請記住,根據您的代碼,基類指針與派生類SmartPtr的引用計數不同。 這意味着如果基類或派生類SmartPtr超出范圍,則指針將變為無效。
編輯 :這絕對有效。 基本的問題是沒有構造函數將指針作為創建SmartPtr的參數。 這是工作代碼。
class Top
{
public:
virtual ~Top(){}
};
class Middle: public Top
{
public:
virtual ~Middle(){}
};
class Bottom: public Middle
{
};
template < typename T >
class SmartPtr
{
public:
explicit SmartPtr(T* ptr):heldPtr(ptr){}
SmartPtr(const SmartPtr<T>& other) : heldPtr(other.heldPtr){}
template<typename U>
SmartPtr(const SmartPtr<U>& other) : heldPtr(dynamic_cast<T*>(other.get())) { }
T* get() const { return heldPtr; }
private:
// built-in pointer held
T *heldPtr;
};
我希望這有幫助。 我還使基類的析構函數具有動態性,因為這是打算繼承的任何類所必需的。
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
class Top { };
class Middle: public Top { };
class Bottom: public Middle { };
template<typename T>
class SmartPtr {
public:
SmartPtr(T* other):heldPtr(other){}
SmartPtr(const SmartPtr<T>& other):heldPtr(other.heldPtr){}
template<typename U>
SmartPtr(const SmartPtr<U>& other) // initialize this held ptr
: heldPtr(other.get()) { } // with other’s held ptr
T* get() const { return heldPtr; }
private:
// built-in pointer held
T *heldPtr; // by the SmartPtr
};
int main()
{
SmartPtr<Top> pt1 = SmartPtr<Middle>(new Middle()); // SmartPtr<Top>
}
您遇到的錯誤很簡單:沒有SmartPtr
構造函數將簡單的T*
(或U*
)作為參數。 添加以下內容:
template <typename U>
SmartPtr(U* ptr): heldPtr(ptr) {}
並且您的代碼應編譯。
關於復制構造函數:確保您傳輸所有權或實現引用計數,否則會遇到麻煩。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.