共享指针和 const 正确性
Posted
技术标签:
【中文标题】共享指针和 const 正确性【英文标题】:Shared pointers and const correctness 【发布时间】:2016-03-21 11:57:30 【问题描述】:将类的 const 正确性 扩展到其指向的成员的正确方法是什么?在示例代码中,get 方法的常量版本是要创建一个std::shared_ptr
,其引用计数器与内部成员m_b
相同,还是从0
重新开始计数?
class A
std::shared_ptr< B > m_b;
public:
std::shared_ptr< const B > get_b( ) const
return m_b;
std::shared_ptr< B > get_b( )
return m_b;
【问题讨论】:
您可能还想实现get_const_b()
,类似于标准容器 (en.cppreference.com/w/cpp/container/vector/begin) 的方法 cbegin()
和 cend()
。
【参考方案1】:
shared_ptr
在您从另一个shared_ptr
构造时将始终保留引用计数; 不安全地使用它的唯一方法是从原始指针构造:shared_ptr<...>(my_ptr.get()) // don't do this
。
您可能还对 propagate_const
包装器感兴趣,它位于 Library Fundamentals TS v2 中,因此可能很快就会在您的实现中可用。
【讨论】:
【参考方案2】:可以通过use_count()
进行一些测试来推断答案。
还要注意方法解析可能不是很明显:
class B ;
class A
std::shared_ptr<B> m_b;
public:
A() m_b = std::make_shared<B>();
std::shared_ptr<const B> get_b() const
std::cout << "const" << std::endl;
return m_b;
std::shared_ptr<B> get_b()
std::cout << "non const" << std::endl;
return m_b;
;
int main(int, char **)
A a;
std::shared_ptr<B> b = a.get_b();
std::cout << b.use_count() << std::endl;
std::shared_ptr<const B> cb = a.get_b();
std::cout << cb.use_count() << std::endl;
const A &a_const_ref = a;
std::shared_ptr<const B> ccb = a_const_ref.get_b();
std::cout << ccb.use_count() << std::endl;
return 0;
输出:
non const
2
non const
3
const
4
【讨论】:
拜托,你能澄清一下这里到底什么是反直觉的,你期望什么样的陷阱?结果对我来说似乎很合乎逻辑和安全。 可以认为第二次调用get_b()
解析为const
版本。此外,第三次调用会增加相同的 ref 计数器,这就是问题本身的答案。
我稍微改写了我的答案,并不是要这么强调陷阱。
谢谢。毕竟这种方法是安全的。以上是关于共享指针和 const 正确性的主要内容,如果未能解决你的问题,请参考以下文章