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

发布于 2024-10-16 23:06:27 字数 1288 浏览 6 评论 0原文

我正在执行斯科特·迈耶斯书中的以下简单程序。我正在使用 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>        ]

请请求帮助解决问题。问题的根本原因是什么?

谢谢!

I am having following simple program from scott meyers book. I am compiling using 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!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

小霸王臭丫头 2024-10-23 23:06:27

您需要实现一个接受 U* 的构造函数。它抱怨它无法显式地将 U* 转换为 SmartPtr

You need to implement a constructor that accepts a U*. It's complaining that it cannot explicitly convert a U* to a SmartPtr<U>.

得不到的就毁灭 2024-10-23 23:06:27

首先,创建两个复制构造函数。一个接受相同类型,另一个接受可以动态转换为基本类型的任何其他类型。这就是我的意思。

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;

};

我希望这有帮助。我还将基类的析构函数设为动态的,因为这是任何要继承的类所必需的。

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. Which mean if either the base-class or derived-class SmartPtr goes out of scope, the pointer will become invalid.

EDIT: This definitely works. The basic issue was there wasn't a constructor that took a pointer as argument to create a 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.

蓦然回首 2024-10-23 23:06:27
SmartPtr<Top> pt1 = SmartPtr<Middle>(new Middle()); //  SmartPtr<Top>
                                               ^^
SmartPtr<Top> pt1 = SmartPtr<Middle>(new Middle()); //  SmartPtr<Top>
                                               ^^
情仇皆在手 2024-10-23 23:06:27
#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>
}
#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>
}
不再让梦枯萎 2024-10-23 23:06:27

您遇到的错误很简单:没有 SmartPtr 的构造函数将简单的 T* (或 U*)作为参数。添加以下内容:

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

您的代码应该可以编译。

关于复制构造函数:确保您传输所有权或实现引用计数,否则您会遇到麻烦。

The error you have is simple: there is no constructor of SmartPtr taking a simple T* (or U*) as a parameter. 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文