我在一本书中遇到这个代码,一个简单的智能指针,有一些关于它的问题:
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. =运算符函数,是不是需要清理旧值?此代码似乎导致引用计数错误。
谢谢,
答案 0 :(得分:3)
你有这本书是垃圾。你需要扔掉它。这段代码甚至都没有编译。
malloc
并不比new unsigned(1)
好。 malloc()
会返回void*
,需要将其转换为unsigned*
,这显然不会在此处完成。为什么不尝试查看boost::shared_ptr
或std::shared_ptr
的实施?无论如何,你最终都会使用它。
答案 1 :(得分:1)
为什么使用
malloc
初始化ref_count?
它也可以使用std::new
。 new
和malloc
之间的主要区别在于new
提供了通过调用其构造函数以及分配动态内存来适当初始化对象的机会。如果内置数据类型如此unsigned int
(如您的示例代码中)基本上这个重要的区别并不重要
请注意,通常std::new
实现也基本上调用malloc
进行内存分配。
= operator
函数,是否需要清除旧值?此代码似乎导致引用计数错误
确实有错误。
此实现中的= operator
检查指针是否被分配给自身,如果是,则正确地将引用计数增加1
,因为在{{1}之后还有一个实体共享此指针被称为。
如果场景不是自我赋值,那么实现应该减少=
指定的指针的引用计数,检查计数是否为1
,如果它是零,则取消分配相同。
答案 2 :(得分:1)
这是错误的代码。自我赋值是非惯用的,可疑地使用malloc
,错误的引用计数实现,在复制赋值运算符/构造函数参数上没有const
,并且不处理SmartPointer
s指向NULL。扔掉你的书,得到一本有效的书。