这是C++吗?指针容器安全吗?
我想要一个类似于 boost 的 scoped_ptr
的安全 C++ 指针容器,但具有类似值的复制语义。我打算将其用于应用程序最内层循环中非常频繁使用的类中很少使用的元素,以获得更好的内存局部性。换句话说,我不关心此类的性能,只要它的“内联”内存负载很小即可。
我已经从以下内容开始,但我对此不太擅长;以下安全吗?我是否在重新发明轮子?如果是,我应该去哪里寻找?
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;}
};
编辑:是的,我们故意让它的行为与正常值非常相似。分析表明该算法在其他方面相当有效,但有时会受到缓存未命中的阻碍。因此,我尝试通过提取当前包含在值中但实际上并未在最内层循环中使用的大 blob 来减小对象的大小。我更愿意在不进行语义更改的情况下做到这一点 - 一个简单的模板包装器将是理想的选择。
I want a safe C++ pointer container similar to boost's scoped_ptr
, but with value-like copy semantics. I intend to use this for a very-rarely used element of very-heavily used class in the innermost loop of an application to gain better memory locality. In other words, I don't care about performance of this class so long as its "in-line" memory load is small.
I've started out with the following, but I'm not that adept at this; is the following safe? Am I reinventing the wheel and if so, where should I look?
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;}
};
Edit: yes, it's intentional that this behaves pretty much exactly like a normal value. Profiling shows that the algorithm is otherwise fairly efficient but is sometimes hampered by cache misses. As such, I'm trying to reduce the size of the object by extracting large blobs that are currently included by value but aren't actually used in the innermost loops. I'd prefer to do that without semantic changes - a simple template wrapper would be ideal.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
不,不是。
您忘记了赋值运算符。
您可以选择通过将赋值运算符声明为私有(并且不实现它)来禁止赋值(允许复制时很奇怪),或者您可以这样实现它:
您还忘记了在复制构造函数中
other.item< /code> 可能为 null(由于默认构造函数),请选择您的替代方案:
对于类似值的行为,我更喜欢
2
,因为值不能为 null。如果您允许空值,请在operator->
和operator*
中引入assert(item);
以确保正确性(在调试模式下) )或抛出异常(无论你喜欢什么)。最后,析构函数中的
item = 0
是无用的:一旦对象被销毁,你就无法在不调用未定义行为的情况下使用该对象......还有 Roger Pate 关于 const-ness 传播更“有价值”的评论-like”,但这更多的是语义问题而不是正确性问题。
No it is not.
You have forgotten the Assignment Operator.
You can choose to either forbid assignment (strange when copying is allowed) by declaring the Assignment Operator private (and not implementing it), or you can implement it thus:
You have also forgotten in the copy constructor that
other.item
may be null (as a consequence of the default constructor), pick up your alternative:For value-like behavior I would prefer
2
, since a value cannot be null. If you go for allowing nullity, introducesassert(item);
in bothoperator->
andoperator*
to ensure correctness (in debug mode) or throw an exception (whatever you prefer).Finally the
item = 0
in the destructor is useless: you cannot use the object once it's been destroyed anyway without invoking undefined behavior...There's also Roger Pate's remark about const-ness propagation to be more "value-like" but it's more a matter of semantics than correctness.
您应该“传递” copy_ptr 类型的 const-ness:
在复制构造函数中不需要指定 T:
为什么要显式设置默认构造函数?仅当您计划在某个地方使用 UB 时,将 dtor 中的指针清空才有意义...
但这些都是小问题,您所拥有的几乎就是这样。是的,我已经多次看到这个发明,但人们每次都会稍微调整语义。您可能会查看 boost::Optional,因为这几乎就是您在呈现时所写的内容,除非您要添加移动语义和其他操作。
You should "pass on" the const-ness of the copy_ptr type:
Specifying T isn't needed in the copy ctor:
Why did you make the default ctor explicit? Nulling the pointer in the dtor only makes sense if you plan on UB somewhere...
But these are all minor issues, what you have there is pretty much it. And yes, I've seen this invented many times over, but people tend to tweak the semantics just slightly each time. You might look at boost::optional, as that's almost what you have written here as you present it, unless you're adding move semantics and other operations.
除了罗杰所说的之外,您还可以通过谷歌搜索“clone_ptr”来获取想法/比较。
In addition to what Roger has said, you can Google 'clone_ptr' for ideas/comparisons.