![](/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.