0

我在一本书中遇到了这段代码,一个简单的智能指针,对此有几个问题:

    template <class T>
class SmartPointer {
 public:
    SmartPointer(T * ptr) {
        ref = ptr;
        ref_count = malloc(sizeof(unsigned));
        *ref_count = 1;
    }
    SmartPointer(SmartPointer<T> & sptr) {
        ref = sptr.ref;
        ref_count = sptr.ref_count;
        ++*ref_count;
    }
    SmartPointer<T> & operator=(SmartPointer<T> & sptr) {
        if (this != &sptr) {
           ref = sptr.ref;
           ref_count = sptr.ref_count;
           ++*ref_count;
        }
        return *this;
    }
    ~SmartPointer() {
        --*ref_count;
        if (*ref_count == 0) {
           delete ref;
           free(ref_count);
           ref = ref_count = NULL;
        }
    }
    T* operator->() { return ref; }
    T& operator*() { return *ref; }
 protected:
    T * ref;
    unsigned * ref_count; 
};

以下是我的问题: 1. 为什么使用 malloc 初始化 ref_count?为什么不能是 ref_count = new unsigned(); 2.=操作符函数,不需要清理旧值吗?此代码似乎会导致引用计数错误。

谢谢,

4

3 回答 3

3

你这本书很垃圾。你需要把它扔掉。这段代码甚至无法编译。

  1. malloc并不比new unsigned(1). malloc()返回void*需要转换unsigned*为显然这里没有完成的返回。
  2. 你是对的,需要注意之前指向的对象的引用计数。

为什么不尝试研究boost::shared_ptror的实现std::shared_ptr呢?无论如何,您很可能最终会使用它。

于 2012-08-29T04:55:20.397 回答
1

为什么使用 ref_count 初始化malloc

它也可以使用std::newnew和之间的主要区别在于mallocnew除了分配动态内存外,它还提供了一个通过调用其构造函数来适当初始化对象的机会。对于像(如您的示例代码)这样​​的内置数据类型unsigned int,本质上这个重要的区别并不重要.
请注意,通常std::new实现也本质上调用malloc内存分配。

函数,= operator不需要清理旧值吗?此代码似乎导致引用计数错误

确实有错误。
= operator这个实现中检查指针是否被分配给自己,如果是,它正确地将引用计数增加1,因为在调用之后还有一个实体共享这个指针=
如果场景不是自分配,那么实现应该减少分配给 by 的指针的引用计数1,检查计数是否0为零,如果它为零,则解除分配。

于 2012-08-29T04:26:41.667 回答
1

这是糟糕的代码。自赋值是非惯用的,糟糕的使用malloc,错误的引用计数实现,const在复制赋值运算符/构造函数参数上没有,并且不处理SmartPointer指向 NULL 的 s。把你的书扔掉,找一本有用的。

于 2012-08-29T05:06:44.520 回答