nis*_*sah 3 c++ const smart-pointers boost-smart-ptr
在boost :: scoped_ptr中operator*,operator->它们是声明的const函数,尽管它们返回T&并且T*可能允许客户端更改底层数据.这违反了逻辑常量的概念(Myers,Effective C++)
const函数不应该有签名吗?
const T& operator*() const;
const T* operator->() const;
Run Code Online (Sandbox Code Playgroud)
这里的基本问题是scoped_ptr对象的行为更像是指针而不是类对象(即使scoped_ptr实例实际上是类对象).
Boost提供的智能指针类旨在尽可能保留原始指针语义†,同时提供附加功能,如引用计数或(在本例中)RAII语义.
为此,编写成员operator*()和operator->()成员scoped_ptr,使其"常量行为"基本上与原始指针的行为相匹配.
用"哑"指针考虑这种情况:
// Can change either Foo or ptr.
Foo* ptr;
// Can't change Foo via ptr, although ptr can be changed.
const Foo* ptr;
// Can't change ptr, although Foo can be changed via ptr.
Foo* const ptr;
// Can't change Foo or ptr.
const Foo* const ptr;
Run Code Online (Sandbox Code Playgroud)
该scoped_ptr类似物是这样的:
// Can change either Foo or ptr.
scoped_ptr<Foo> ptr;
// Can't change Foo via ptr, although ptr can be changed.
scoped_ptr<const Foo> ptr;
// Can't change ptr, although Foo can be changed via ptr.
const scoped_ptr<Foo> ptr;
// Can't change Foo or ptr.
const scoped_ptr<const Foo> ptr;
Run Code Online (Sandbox Code Playgroud)
编写运算符的方式使得上面的代码片段成为可能,即使scoped_ptr它实际上不是原始指针.
在所有情况下,代码都需要能够取消引用ptr.通过创建运算符const,可以在const非const scoped_ptrs 和非s 上调用dereference/member-access运算符.
请注意,如果用户声明a scoped_ptr<Foo>,它将具有以下成员:
Foo& operator*() const;
Foo* operator->() const;
Run Code Online (Sandbox Code Playgroud)
而a scoped_ptr<const Foo>会有这些成员:
const Foo& operator*() const;
const Foo* operator->() const;
Run Code Online (Sandbox Code Playgroud)
所以指针的const-correctness行为实际上是以这种方式保留的.
† 但不多了,否则他们不会是聪明的指针!
| 归档时间: |
|
| 查看次数: |
510 次 |
| 最近记录: |