关于这个智能指针类

时间:2012-08-29 04:12:28

标签: c++

我在一本书中遇到这个代码,一个简单的智能指针,有一些关于它的问题:

    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. =运算符函数,是不是需要清理旧值?此代码似乎导致引用计数错误。

谢谢,

3 个答案:

答案 0 :(得分:3)

你有这本书是垃圾。你需要扔掉它。这段代码甚至都没有编译。

  1. malloc并不比new unsigned(1)好。 malloc()会返回void*,需要将其转换为unsigned*,这显然不会在此处完成。
  2. 你是对的,需要注意以前指出的对象的引用计数。
  3. 为什么不尝试查看boost::shared_ptrstd::shared_ptr的实施?无论如何,你最终都会使用它。

答案 1 :(得分:1)

  

为什么使用malloc初始化ref_count?

它也可以使用std::newnewmalloc之间的主要区别在于new提供了通过调用其构造函数以及分配动态内存来适当初始化对象的机会。如果内置数据类型如此unsigned int(如您的示例代码中)基本上这个重要的区别并不重要 请注意,通常std::new实现也基本上调用malloc进行内存分配。

  

= operator函数,是否需要清除旧值?此代码似乎导致引用计数错误

确实有错误。
此实现中的= operator检查指针是否被分配给自身,如果是,则正确地将引用计数增加1,因为在{{1}之后还有一个实体共享此指针被称为。
如果场景不是自我赋值,那么实现应该减少=指定的指针的引用计数,检查计数是否为1,如果它是零,则取消分配相同。

答案 2 :(得分:1)

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