簡體   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