c++ - boost::scoped_ptr 是否违反逻辑常量准则

标签 c++ constants 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;

最佳答案

这里的根本问题是 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;

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-correctness 行为实际上是以这种方式保留的。

但不能再多了,否则它们就不是智能指针了!

关于c++ - boost::scoped_ptr 是否违反逻辑常量准则,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6718538/

相关文章:

c++ - 从文本文件 : weird behaviour 中读取单词

c++ - 为什么CPP中有定义常量和声明常量?

c++ - 对 const 的右值引用有什么用吗?

c++ - 如何使用智能指针围绕 C 'objects' 实现包装器?

c++ - 元组的运行时索引

c++ - 暂停播放时 QMediaPlayer 崩溃

c++ - 如何将现有对象 push_back 到共享指针 vector ?

c++ - 智能指针运算符=

c# - 如何将结构从 C# 编码到 C++?

php - 在 Symfony 中使用命名空间时出现未定义常量错误