在同一步骤中构造新对象和赋值


const ClassA& curShot = vec_shots[curShotIndx];

在上面的代码中,curShot 对象是在同一步骤中构造和分配的。我的问题是在上面的语句中使用了哪个构造函数。我以为它将是默认构造函数,后跟赋值运算符,但它似乎调用了复制构造函数。为什么会这样呢?

发生的情况是

vec_shots[curShotIndx];

返回分配给 const ClassA& curShot 的引用。此步骤不涉及对象创建。因此,不会调用任何构造函数(既不是默认构造函数也不是复制构造函数)。

赋值运算符也不会被调用,因为您没有将一个对象实例分配给另一个对象实例,而只是将一个引用分配给另一个对象实例。在此代码中,您不会处理多个(现有)对象实例。因此,不会调用任何构造或赋值。

既然你写了"它似乎调用了复制构造函数",我假设你问题中的与号是一个错字
在这种情况下,如果你愿意这样做

const ClassA curShot = vec_shots[curShotIndx];

它被评估为复制构造。它和丑陋的const ClassA curShot( vec_shots[curShotIndx] )一样.

但是,如果你写

ClassA curShot;  // I skipped the "const", because otherwise the example would be invalid.
curShot = vec_shots[curShotIndx]; 

然后调用默认构造函数,并在第二行调用opearator=


此外,"="如此之多可能意味着既不调用复制构造函数 NOR operator=,你可以有这个:

const ClassA f(){ return ClassA(); }
//...
const ClassA curShot = f();  // we would expect here a copy constructor call

在这里 - 如果编译器使用返回值优化并且通常这样做 - 则只为 curShot 调用默认构造函数。

不使用构造函数,curShot是一个引用,一个已经存在的对象的别名,而不是一个独立的对象本身。

此外,初始化和赋值不能在同一步骤中完成。例如,假设你有

 ClassA original;
 ClassA copy = original;

在这里,copy没有original分配,而是使用 original 启动的。这称为副本初始化。

如果你这样做了

 ClassA copy2(original);

这称为直接初始化。

复制构造函数将在两个实例中调用。(可能会发生复制省略,因此可能不会调用它,但必须可用)

赋值是指对现有对象使用 operator =

 ClassA x;
 ClassA y;
 x = y;     //assignment

此语句仅将 curShot 定义为引用,它不是一个新对象。

最新更新