繁体   English   中英

我自己的智能指针模板编译错误

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM