【发布时间】:2017-02-02 19:45:53
【问题描述】:
出于教育目的,我今天早些时候实现了一个包装类,定义如下(摘自一本书):
#ifndef WRAPPER_H
#define WRAPPER_H
template<class T>
class Wrapper
{
public:
Wrapper()
{ dataPtr = 0; }
Wrapper(const T& inner)
{
dataPtr = inner.clone();
}
Wrapper(const Wrapper<T> &original)
{
if (original.dataPtr != 0)
dataPtr = original.dataPtr->clone();
else
dataPtr = 0;
}
Wrapper &operator =(const Wrapper<T> &original)
{
if (this != &original)
{
if (dataPtr != 0)
delete dataPtr;
dataPtr = (original.dataPtr !=0) ? original.dataPtr->clone() : 0;
}
return *this;
}
~Wrapper()
{
if (dataPtr != 0)
delete dataPtr;
}
T &operator*()
{
return *dataPtr;
}
const T&operator*() const
{
return *dataPtr;
}
T *operator->()
{
return dataPtr;
}
const T * const operator->() const
{
return dataPtr;
}
private:
T *dataPtr;
};
#endif
主要思想是充当指针,并具有处理内存管理、复制构造函数、析构函数和赋值运算符的额外优势。它包装了具有克隆方法的类:它们返回一个指向自身副本的指针(而不是自身,指向使用newClass(*this) 制作的新副本)。
在某些方面它看起来像unique_ptr,因为被包装的对象只能通过这个包装器访问。但是,有一个区别,这就是我的问题所在。在这个包装类中,有一个构造函数,它通过接受对其包装的类的对象的引用来定义(上面代码中的第一个构造函数)。
这很方便。假设我们有类A 和B,B 的构造函数引用了Wrapper< A >。然后我可以用另一个对象A构造一个对象B:
A object1;
B object2(A);
这是因为object2是使用前面提到的Wrapper构造函数来构造一个Wrapper< A >(然后传递给B的构造函数)。
是否可以使用std::memory 中的任何智能指针来执行此操作?我的主要目标是教育,但实际上我不想重新发明轮子。
【问题讨论】:
-
复制构造函数不可用于唯一指针,因为它们在复制后将不再唯一。相反,共享指针是可复制的,其中副本只是强制执行它们共享>指向对象的所有权这一事实。
-
这看起来像是在做深拷贝,而不是共享/移动指针。
-
看起来像一个 intrusive_ptr
-
你应该使用
nullptr而不是0,并且析构函数中的空检查是没有意义的。 -
我认为检查是不必要的。我从未测试过空指针的尖锐程度,但顾名思义它是尖的。
标签: c++ wrapper shared-ptr