boost::scoped_ptr是否违反了逻辑一致性原则?
Does boost::scoped_ptr violate the guideline of logical constness
在boost::scoped_ptr中,operator*
和operator->
被声明为const
函数,尽管它们返回T&
和T*
,这可能允许客户端更改底层数据。这违反了逻辑一致性的思想(Myers, Effective c++)
const函数不应该有签名吗?
const T& operator*() const;
const T* operator->() const;
这里的基本问题是scoped_ptr
对象的行为更像指针而不是类对象(尽管scoped_ptr
实例实际上是类对象)。
Boost提供的智能指针类被设计成尽可能地保留原始指针语义,同时提供额外的功能,如引用计数或(在这种情况下)RAII语义。
为此,scoped_ptr
的operator*()
和operator->()
成员被写入,使其"constness行为"本质上与原始指针相匹配。
考虑"哑"指针的这种情况:
// 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;
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;
操作符的编写方式使得上面的代码片段成为可能,即使scoped_ptr
实际上不是一个原始指针。
在所有情况下,代码需要能够解引用ptr
。通过将操作符设置为const
,可以在const
和非const
的scoped_ptr
上调用解引用/成员访问操作符。
请注意,如果用户声明了一个scoped_ptr<Foo>
,它将具有这些成员:
Foo& operator*() const;
Foo* operator->() const;
而scoped_ptr<const Foo>
则有以下成员:
const Foo& operator*() const;
const Foo* operator->() const;
因此,指针的const正确性行为实际上是这样保留的。
†但是没有更多,否则它们就不是智能指针了!
在boost::scoped_ptr中operator*和operator->被声明为const函数,尽管它们返回T&和T*,这可能允许客户端更改底层数据。
"底层数据"不是智能指针值的一部分。如果两个(智能)指针指向同一个对象,则它们相等:a == b
和&*a == &*b
。
这违反了逻辑一致性的思想(Myers, Effective c++)
不,它没有:
智能指针的逻辑值只取决于它所指向的对象。
解除对智能指针的引用不会改变它指向的对象。
所以解引用一个智能指针并不会改变它的逻辑值(或者它的状态,如果你喜欢的话)。
QED
一个scoped_ptr<T>
就像一个T*
。它不像T* const
.
一个scoped_ptr<T const>
就像一个T const*
(你可以写为const T*
)和只有在你会期望operator*
和operator->
返回const
的东西。
- 缓存std::数组的选定元素,并在c++中自动保持其一致性
- С++ wxWidgets:代码架构,设计原则和模式
- 标准::make_pair 和标准::make_optional之间的一致性
- 可以从std::string继承以提供类型一致性吗
- 我需要如何更改我的程序以使用打开/关闭原则?
- 标记为 std::memory_order_seq_cst 的单个原子操作是否会在所有位置触发顺序一致性?
- 复制赋值函数如何访问另一个对象的私有成员(Stroustroup 原则和实践书)?
- 顺序一致性和获取/发布语义有什么区别?
- 用于验证 Visual Studio 一致性开关对生成的代码的影响的工具
- Visual Studio 2017扩展选项卡中的C++核心指导原则检查器丢失
- 是否有一种设计模式或面向对象的基本原则来处理这种共享资源的情况?
- 获取/发布与 C++11 中的顺序一致性?
- 为什么'acquire/release'不能保证 c++11 中的顺序一致性?
- 分层状态机涉及哪些原则,以及如何实现基本模型?
- 如何应用注册表模式使"select class depend on input"遵守开放封闭原则?
- C++指针输出一致性
- 跨依赖类的状态一致性
- 不兼容的操作原则到三元op
- 代码在Visual C ++中无法按预期工作(来自bjarne stroustrup编程和原则书籍2n版本的示例)
- boost::scoped_ptr是否违反了逻辑一致性原则?