【问题标题】:Does std::swap of smart pointers guarantee the references to be unchanged?智能指针的 std::swap 是否保证引用不变?
【发布时间】:2019-08-21 09:01:27
【问题描述】:

智能指针的 std::swap 是否保证引用(内存中的地址)不变?

std 文档指出,让class T 可交换的一个(几个)合格特征是,

T 必须是可赋值的并且 T 必须是可复制和/或移动构造的

如果交换是通过使用复制构造进行的,我怀疑内存地址可能会改变。但是,我也怀疑在交换特定(智能)指针时,通过复制构造进行交换是不相关的。

下面的代码编译(GCC)并且在交换时不改变地址的情况下顺利运行,但是我能保证会这样吗?

注意:示例使用std::auto_ptr,因为在 cmets 中指出 std 代码优于 boost。我在旧的 C++ 上工作,没有可用的 std::unique_ptr(尽管如此,它的复制构造函数被删除了)。原帖申请boost::scoped_ptr

#include <boost/scoped_ptr>
#include <iostream>

class Awesome
{
public:
    Awesome(int a=0) : Value(a) {}
    Awesome(const Awesome& T) : Value(T.Value) {}
    int Value;
};

int main()
{
    std::auto_ptr<Awesome> a_ptr(new Awesome(2));
    Awesome& a_ref = *a_ptr.get();

    std::cout << "a_ptr's addr : " << a_ptr.get() << std::endl;
    std::cout << "a_ref's addr : " << &a_ref << std::endl;

    std::auto_ptr<Awesome> b_ptr;
    std::swap(b_ptr, a_ptr); // <<------------------ Does this (possibly) break 'a_ref' ?

    std::cout << "b_ptr's addr : "<< b_ptr.get() << std::endl;

    return 0;
}

【问题讨论】:

  • 如果它是用std::swap 提出的,那将是一个更多更好的问题。
  • @Bathsheba .. 注意到。然后我会编辑,但我真的会使用 boost。
  • 原因当然是Boost没有标准化,所以这个问题很难回答。出于兴趣,你为什么不能使用std::swap?虽然我喜欢 Boost,但只要功能成为标准 C++,我总是会迁移。
  • 不,只要对象没有超出范围,引用 a_ref 将是有效的。
  • 不要使用auto_ptr ... C++17 中不再存在。

标签: c++ boost swap


【解决方案1】:

您正在交换指针,而不是对象本身,swap() 函数无法更改对象的地址,因为它甚至不知道对象。 如果您正在寻找保证,那么您应该要求保证销毁和移动/复制智能指针不会影响对象。

edit:这与std::swap(b_ptr, a_ptr); 相关,在 boost 中,智能指针上有一个成员函数交换,所以理论上它可以做任何事情,但我非常怀疑它会在交换指针时改变对象的地址。

【讨论】:

  • 感谢您对 boost 成员交换的评论。我没有想到。我同意它不太可能做任何可疑的事情,但是,记住这一点很好,我会检查它的实现。
猜你喜欢
  • 1970-01-01
  • 2021-12-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-16
相关资源
最近更新 更多