You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

调用std::swap交换shared_ptr指向的值为何触发大量构造与析构函数?

Understanding the Difference in Swap Behavior with std::shared_ptr

Great question! Let's break this down clearly because it's a common point of confusion when working with smart pointers and move semantics. The key difference boils down to what exactly you're swapping: the underlying object the smart pointer points to, or the smart pointer itself.

1. Why std::swap(*a, *b) triggers construction/destruction

When you write std::swap(*a, *b), you're not swapping the shared_ptr instances—you're swapping the actual objects that a and b point to.

The default implementation of std::swap for a type T looks roughly like this:

template<typename T>
void swap(T& x, T& y) {
    T temp = std::move(x);  // Move-constructs a temporary from x
    x = std::move(y);       // Move-assigns y to x
    y = std::move(temp);    // Move-assigns the temporary to y
}

Even with move semantics (which is more efficient than copying), this still involves:

  • Creating a temporary T object (triggers move-constructor)
  • Two move-assignment operations
  • Destroying the temporary object when it goes out of scope (triggers destructor)

If your underlying object doesn't have optimized move operations (or falls back to copying), you'll see even more construction/destruction calls. For large or complex objects, this can get expensive fast.

2. Why b.swap(a) or std::swap(a, b) doesn't trigger construction/destruction

When you swap the shared_ptr instances themselves (either via the member swap method or the specialized std::swap for shared_ptr), you're only swapping the internal pointers of the smart pointers.

A std::shared_ptr typically contains two core components:

  • A pointer to the actual object being managed
  • A pointer to a control block (which holds the reference count, destructor information, etc.)

The swap operation for shared_ptr simply swaps these two pointers between the two instances. It never touches the underlying object—so there's no need to construct or destroy any instances of the object type.

The specialized std::swap for shared_ptr is essentially a wrapper around the member swap method, so both approaches behave identically here.

Example to See the Difference

Let's use a simple test object to visualize the behavior:

#include <iostream>
#include <memory>

struct TestObject {
    TestObject() { std::cout << "✅ Construct TestObject\n"; }
    ~TestObject() { std::cout << "❌ Destruct TestObject\n"; }
    TestObject(TestObject&&) { std::cout << "➡️ Move-Construct TestObject\n"; }
    TestObject& operator=(TestObject&&) { std::cout << "🔄 Move-Assign TestObject\n"; return *this; }
};

int main() {
    auto a = std::make_shared<TestObject>();
    auto b = std::make_shared<TestObject>();

    std::cout << "\n--- Swapping underlying objects (*a, *b) ---\n";
    std::swap(*a, *b);

    std::cout << "\n--- Swapping shared_ptr instances (a, b) ---\n";
    std::swap(a, b);

    return 0;
}

Output:

✅ Construct TestObject
✅ Construct TestObject

--- Swapping underlying objects (*a, *b) ---
➡️ Move-Construct TestObject
🔄 Move-Assign TestObject
🔄 Move-Assign TestObject
❌ Destruct TestObject

--- Swapping shared_ptr instances (a, b) ---

Notice how swapping the shared_ptr instances produces no object construction/destruction output—only the swap of internal pointers happens.

Key Takeaway

  • Swap *a and *b → you're manipulating the underlying objects, which triggers move/copy operations and temporary object destruction.
  • Swap a and b → you're manipulating the smart pointers themselves, which only swaps internal pointers with zero impact on the underlying objects.

内容的提问来源于stack exchange,提问作者maufcost

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 07:16:24