我想要一个安全的C++指针容器,类似于boost的scoped_ptr,但是具有类似于值的复制语义。为了获得更好的内存局部性,我打算将它用于应用程序最内部循环中使用非常频繁的类中很少使用的元素。换句话说,只要这个类的“内联”内存负载很小,我就不关心它的性能。
我是从以下几个方面开始的,但我不太擅长这一点;下面是安全的吗?我是在重新发明轮子吗?如果是的话,我应该去哪里看?
template <typename T>
class copy_ptr {
T* item;
public:
explicit copy_ptr() : item(0) {}
explicit copy_ptr(T const& existingItem) : item(new T(existingItem)) {}
copy_ptr(copy_ptr<T> const & other) : item(new T(*other.item)) {}
~copy_ptr() { delete item;item=0;}
T * get() const {return item;}
T & operator*() const {return *item;}
T * operator->() const {return item;}
};编辑:是的,这是有意的,它的行为与正常值几乎完全一样。分析表明,该算法在其他方面是相当有效的,但有时由于缓存丢失而受到阻碍。因此,我试图通过提取当前按值包含但实际上不在最内部循环中使用的大块来缩小对象的大小。我更喜欢在没有语义变化的情况下这样做--一个简单的模板包装器将是理想的。
发布于 2010-11-06 13:24:44
不不是的。
您忘记了赋值操作符。
您可以通过声明赋值操作符私有(而不是实现它)来选择禁止赋值(允许复制时很奇怪),也可以这样实现它:
copy_ptr& operator=(copy_ptr const& rhs)
{
using std::swap;
copy_ptr tmp(rhs);
swap(this->item, tmp.item);
return *this;
}在复制构造函数中,您还忘记了other.item可能为null (作为默认构造函数的结果),请选择以下选项:
// 1. Remove the default constructor
// 2. Implement the default constructor as
copy_ptr(): item(new T()) {}
// 3. Implement the copy constructor as
copy_ptr(copy_ptr const& rhs): item(other.item ? new T(*other.item) : 0) {}对于类似值的行为,我更喜欢2,因为值不能为null。如果您希望允许无效,请在assert(item);和operator->中引入operator*,以确保正确性(在调试模式下)或抛出异常(无论您喜欢什么)。
最后,析构函数中的item = 0是无用的:如果不调用未定义的行为,那么一旦对象被销毁,就不能使用它.
还有Roger关于const-ness传播的评论,说得更像“价值”,但这更多的是语义问题,而不是正确性问题。
发布于 2010-11-06 12:56:19
您应该“传递”copy_ptr类型的一致性:
T* get() { return item; }
T& operator*() { return *item; }
T* operator->() { return item; }
T const* get() const { return item; }
T const& operator*() const { return *item; }
T const* operator->() const { return item; }在副本ctor中不需要指定T:
copy_ptr(copy_ptr const &other) : item (new T(*other)) {}为什么要将默认的ctor显式化?只有当你计划在UB的某个地方时,才有意义取消dtor中的指针.
但这些都是小问题,你所拥有的几乎就是它。是的,我已经看过很多次这个发明了,但是人们每次都会稍微修改一下语义。您可能会看到boost::可选的,因为这几乎是您在这里展示它时所写的,除非您正在添加移动语义和其他操作。
发布于 2010-11-06 12:59:23
除了罗杰所说的,你还可以用谷歌搜索“clone_ptr”来进行想法/比较。
https://stackoverflow.com/questions/4113125
复制相似问题