【问题标题】:smart pointer implementation for derived to base pointers派生到基指针的智能指针实现
【发布时间】:2011-08-14 14:01:51
【问题描述】:

我已经创建了一个智能指针实现,如下所示::

#include <iostream>
#include <vector>
using namespace std;
class Obj {
   int i, j;
public:
   Obj() { i = 0 ; j = 0 ; }
   Obj(int ii , int jj) : i(ii) , j(jj) { }
   void f() { cout << i << endl; }
   void g() { cout << j << endl; }
};

class ObjDerived : public Obj
{
    int k;
    public:
    ObjDerived(int kk = 0) :k(kk) { }
    void h() { cout << k << endl; }
};


template <typename ULT >
class SP
{
       ULT* ptr;

    public:
       explicit SP(ULT* tptr = NULL) : ptr(tptr) { }
       template <typename OTHER>
       SP(SP<OTHER>& other)
       {
           ptr = (ULT*)other.ptr;
       }    

       ULT* operator->() { return ptr; }
       ULT& operator*() { return *ptr; }
       SP<ULT>& operator=(SP<ULT>& tptr)
       {
           if(ptr != tptr.ptr)
               ptr = tptr.ptr;
           return *this;
       }
       SP<ULT>& operator=(ULT* tptr)
       {
           ptr = tptr;
           return *this;
       }

       template <typename OTHER>
       SP<ULT>& operator=(SP<OTHER>& der) // ??
       {
           cout << "In operator\n";
           this->ptr = (ULT*)der.ptr;
           return *this;
       }

       ~SP() 
       { 
           if(ptr != NULL )
               delete ptr; 
       }
};


int main() 
{
    SP<Obj> Sptr2(new Obj(10,20));

    SP<ObjDerived> Sptr4(new ObjDerived(80));
    Sptr2 = Sptr4; //error in this line
    return 0;


}

我正在尝试使用智能指针 SP 将派生类指针转换为基类指针。 operator= 成员函数

template <typename OTHER>
SP<ULT>& operator=(SP<OTHER>& der) // ??
{
     cout << "In operator\n";
     this->ptr = (ULT*)der.ptr;
     return *this;
}

出现以下错误 ---> 错误:'ObjDerived* SP::ptr' 是私有的

我不知道如何使用智能指针实现所需的指针转换。我还搜索了以前有关智能指针的帖子,但找不到我的问题的确切答案。

【问题讨论】:

  • 您的复制和赋值行为是错误的——这将导致旧对象泄漏并删除新对象两次。此外,C 风格的强制转换会默默地允许无效的指针转换,这可能会导致通过不兼容的指针类型错误地删除对象。
  • “我已经创建了一个智能指针实现”。为什么?
  • @Johnsyweb:作为一种学习练习,这是一件好事。最重要的教训是,要做到正确非常困难。
  • @Mike:完全同意。不幸的是,有些人将这些练习包含在生产代码中。

标签: c++


【解决方案1】:

您可以提供公共 get() 函数成员来检索原始指针。通常智能指针提供此功能。小例子:

template <typename ULT >
class SP {
// ...

ULT* get() const {return ptr;}

 template <typename OTHER>
 SP<ULT>& operator=(SP<OTHER>& der) {
     cout << "In operator\n";
     this->ptr = (ULT*)der.get();
     return *this;
 }

};

您还可以查看Effective C++ 的第 45 项,了解有关创建智能指针的更多信息。

我假设您这样做是为了训练任务,因为有相当不错的智能指针实现,例如,boost::shared_ptr

【讨论】:

  • 是的,在某种程度上这是一项自我训练任务。我会尝试使用 boost::shared_ptr。
【解决方案2】:

那么成员 ptr 是私有的 - 将其公开或提供公共访问方法。

【讨论】:

    【解决方案3】:

    您是否考虑过使用Boost smart pointers 而不是尝试自己动手?他们已经经历了实现好的智能指针类的所有痛苦。即使由于某种原因你不能使用 Boost,你仍然可以从他们的课程中学到很多东西。

    【讨论】:

      【解决方案4】:

      您可以将成员 ptr 设为私有。或者您可以使用内置的复制机制: 而不是,

      this->ptr = (ULT*)der.ptr;  // ptr needs to be accessible
      

      执行以下操作:

      *this = *((ULT*&)der);  // copy using in-built shallow copy
      

      【讨论】:

        猜你喜欢
        • 2017-03-16
        • 2016-12-08
        • 1970-01-01
        • 2021-09-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-04-29
        • 1970-01-01
        相关资源
        最近更新 更多