c++中按值传递时的复制顺序

Sequencing of the copying when passing by value in C++

本文关键字:复制 顺序 按值传递 c++      更新时间:2023-10-16

在c++中,当按值传递对象时,是否对何时进行复制有限制?

我有以下代码(简化):

class A;
class Parent
{
public:
    void doSomething(std::auto_ptr<A> a); // meant to transfer ownership.
};
std::auto_ptr<A> a = ...;
a->getParent()->doSomething(a);

作用如下:

std::auto_ptr<A> a = ...;
std::auto_ptr<A> copy(a);
a->getParent()->doSomething(copy);

这显然会导致段错误,因为a现在引用NULL

而不是:

std::auto_ptr<A> a = ...;
Parent* p = a->getParent();
p->doSomething(a);

A: auto_ptr在较新的c++版本中已弃用,我建议检查unique_ptr。

B:这种行为是预料之中的。auto_ptr对象拥有它所创建的对象。因此,如果您希望正确地将所有权从一个auto_ptr转移到另一个auto_ptr,则原始auto_ptrs托管对象将正确地为空指针。虽然我相信这个逻辑是由std::auto_ptr库处理的,您不应该做任何特殊的事情来获得这个行为。如果允许两个auto_ptrs管理同一个对象,那么当它们超出作用域时,它们也会尝试释放该对象的内存。这本身就很糟糕,但更糟糕的是,如果其中一个auto_ptr有更大的作用域,它可能会试图引用不再保存该对象的内存,因为它已经被另一个auto_ptr释放了,在这种情况下,我们会遇到真正的混乱。因此,当所有权转移时,原始指针托管对象被设置为null,我们就有了安全的错觉。:)

在我看来,这个例子并不好,至少有三个原因。

1)在没有看到doSomething原型的情况下查看代码,不清楚所有权是否可以改变。

2)如果结果可能取决于求值的顺序,那么代码是不可移植的或依赖于实现的,因此是不可接受的。

3)即使求值顺序是正确的,代码也可以从其他代码中提出这个确切的问题开发者会浪费他们的时间。可读性必须是最高优先级。