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 定义为引用,它不是一个新对象。