简体   繁体   English

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

[英]my own smart pointer template compilation error

I am having following simple program from scott meyers book. 我正在遵循斯科特·迈耶斯书中的简单程序。 I am compiling using Visual studio 2009. 我正在使用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>
}

During compilation i am getting following error 在编译期间我遇到以下错误

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>        ]

Kindly request to help in resolving problem. 请请求帮助解决问题。 What is root cause of problem? 问题的根本原因是什么?

Thanks! 谢谢!

You need to implement a constructor that accepts a U* . 您需要实现一个接受U*的构造函数。 It's complaining that it cannot explicitly convert a U* to a SmartPtr<U> . 抱怨不能将U*明确转换为SmartPtr<U>

SmartPtr<Top> pt1 = SmartPtr<Middle>(new Middle()); //  SmartPtr<Top>
                                               ^^

First of all, create two copy constructors. 首先,创建两个副本构造函数。 One to accept the same type and the other to accept any other type that can be dynamically casted to the base type. 一个接受相同类型,另一个接受可以动态转换为基本类型的任何其他类型。 Here's what I mean. 这就是我的意思。

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
}

Do keep in mind that according to your code, the base class pointer is not keeping the same reference count as the derived class SmartPtr. 请记住,根据您的代码,基类指针与派生类SmartPtr的引用计数不同。 Which mean if either the base-class or derived-class SmartPtr goes out of scope, the pointer will become invalid. 这意味着如果基类或派生类SmartPtr超出范围,则指针将变为无效。

EDIT : This definitely works. 编辑 :这绝对有效。 The basic issue was there wasn't a constructor that took a pointer as argument to create a SmartPtr. 基本的问题是没有构造函数将指针作为创建SmartPtr的参数。 Here's the working code. 这是工作代码。

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;

};

I hope this helps. 我希望这有帮助。 I also made the destructors of the base classes dynamic because that's required of any classes that are intended to be inherited. 我还使基类的析构函数具有动态性,因为这是打算继承的任何类所必需的。

#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>
}

The error you have is simple: there is no constructor of SmartPtr taking a simple T* (or U* ) as a parameter. 您遇到的错误很简单:没有SmartPtr构造函数将简单的T* (或U* )作为参数。 Add the following: 添加以下内容:

template <typename U>
SmartPtr(U* ptr): heldPtr(ptr) {}

and your code should compile. 并且您的代码应编译。

With regard to the copying constructors: make sure you either transmit ownership or implement reference counting, otherwise you'll be in trouble. 关于复制构造函数:确保您传输所有权或实现引用计数,否则会遇到麻烦。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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