c++ - 在共享指针的值中调用 std::swap 会调用一堆构造函数和析构函数

标签 c++ c++11 shared-ptr move-semantics

我最近开始学习 move 语义和共享指针,但在尝试理解它时遇到了很多困难。

我目前正在上一门关于这些主题的类(class),但是讲师没有解释为什么当我们交换指针中包含的值时会调用这些构造函数和析构函数。在共享指针(如 b.swap(a))和 std::swap(a, b) 中调用 swap 不调用任何构造函数或析构函数,而调用 std::swap(*a, * b) 正在调用他们中的一群人。

主要代码:

int main(int argc, char** argv){

    std::shared_ptr<strc> a = std::make_shared<strc>("one");
    std::shared_ptr<strc> b = std::make_shared<strc>("two");

    message("b.swap(a)"); // No constructors or destructors are called.
    b.swap(a);
    disp(a);
    disp(b);

    message("std::swap"); // A bunch of constructors and destructors are called.
    std::swap(*a, *b);
    disp(a);
    disp(b);

    message("std::swap"); // No constructor or destructors are called.
    std::swap(a, b);
    disp(a);
    disp(b);

    return 0;
}

“strc”的实现类是(为了简洁起见,我只展示其中的“重要”实现):

strc::strc(strc && o){
    msg("Move Constructor.");
    this->data = std::move(o.data);
    o.data = nullptr;
}

strc::~strc(){
    msg("Destructor.");
    delete [] data;
}

strc & strc::operator = (strc o){
    msg("Copy and Swap (=).");
    swap(o);
    return *this;
}

void strc::swap(strc & o){
    msg("Calling std::swap");
    std::swap(this->data, o.data);
}

这是打印到控制台的内容(让我更多地了解正在发生的事情,并对 move 语义和共享指针有透彻的了解)。

调用 b.swap(a) 一 (1) 两 (1) 个

调用 std::swap(*a, *b) strc: move 构造函数。 strc: move 构造函数。 strc: copy-and-swap (=)。 strc:调用 std::swap strc:析构函数。 strc: move 构造函数。 strc: copy-and-swap (=)。 strc:调用 std::swap strc:析构函数。 strc:析构函数。 两个 (1) 一 (1) 个

调用 std::swap(a, b) 一 (1) 两 (1) 个

这是为什么呢?它与 move 语义有关吗?它不应该调用标准交换函数吗?我不明白这些交换调用之间的区别,以及为什么其中一个调用所有这些构造函数和析构函数。

最佳答案

  1. b.swap(a) 交换指针。
  2. std::swap(*a, *b) 交换指向对象的内容。
  3. std::swap(a, b) 再次交换指针。

案例 2 中使用了 move 构造函数。这就是它们的用途。

在情况 1 和 3 中也使用了 move 构造函数,但是您没有观察到这一点,因为您没有修改 std::shared_ptr 构造函数。

您可以在此处了解更多信息 Should the Copy-and-Swap Idiom become the Copy-and-Move Idiom in C++11?

关于c++ - 在共享指针的值中调用 std::swap 会调用一堆构造函数和析构函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49095423/

相关文章:

c++ - 由于引用计数器原子递增/递减,shared_ptrs 是否会遇到缓存未命中?

c++ - 从 int 到 shared_ptr 的隐式转换

c++ - 如何创建一个将其参数转发给 fmt::format 保持类型安全的函数?

c++ - 在 C++0x 标准中会有 unordered_map,这与 boost unordered_map 相比如何?

c++ - 使用 C++ STL 进行 iOS 开发有什么限制?

c++ - C& 运算符中的 &= 是什么意思=(const C&) & = default;做?

c++ - 如何强制在编译时评估 constexpr 函数

c++ - 任何人都知道有什么计划让 ^ 成为 shared_ptr<T> 的简写吗?

c++ - 进程A直接写入进程B的数据成员

c++ - static_cast 指针类型的性能影响?