赋值操作和对象传递期间的构造函数调用

Constructor calls during assignment operations and object passing

本文关键字:函数调用 操作 对象 赋值      更新时间:2023-10-16

我对通过引用和按值传递对象到特定类的函数之间的差异感到困惑。如果我按值传递对象,我知道默认复制构造函数会逐个成员复制对象以在给定函数中使用。但是,如果我将对象作为需要深度复制的类的常量引用传递,是否仍调用复制构造函数?说我有一个功能

     void debug(const MyClass& object1); 

传递对象 1 会调用复制构造函数吗?还是对象直接传递到函数中而不进行复制?还有一个问题 - 如果我有一个名为分数的类 -

     Fraction A(1,2); // 1 is this numerator, 2 the denominator
     A = Fraction(2,3);

上述行是否调用默认构造函数来制作临时对象 Fraction(2,3(,然后是赋值运算符?

谢谢。

Would passing object1 call the copy constructor?

不,它不会调用复制构造函数,因为通过引用传递在这种情况下不制作副本

A = Fraction(2,3);
是的,

它将调用具有两个参数的构造函数(如果两个参数都有默认值,则调用默认构造函数(,然后调用复制赋值运算符。

您可以看到以下代码的输出:

 #include <iostream>
 using namespace std;
 class Fraction
 {
  public:
  int denom;
  int nominator;
  Fraction(int d , int n ):denom(d), nominator(n)
  {
    cout << "call non-copy constructor" <<endl;
  }
  Fraction(const Fraction&  rhs)
  {
    cout << "call copy constructor" <<endl;
    denom = rhs.denom;
    nominator = rhs.nominator;
  }
  const Fraction& operator=(const Fraction&  rhs)
  {
   cout << "call copy assignment operator" << endl;
   if (this == &rhs)
   {
      return *this;
   }
   denom = rhs.denom;
   nominator = rhs.nominator;
   return *this;
   }
};
void debug(const Fraction& obj)
{
  cout << "this is debug: pass by reference " <<endl;
}
void debugPassByValue(Fraction obj)
{
  cout << "this is debug: pass by value" <<endl;
}
int main()
{
  Fraction A(1,2);
  cout << "--------------" <<endl;
  debug(A);
  cout << "--------------" <<endl;
  A = Fraction(2,3);
  cout << "--------------" <<endl;
  debugPassByValue(A);
  cout << "--------------" <<endl;
  cin.get();
  return 0;

}

您将看到以下输出:

call non-copy constructor  //Fraction A(1,2);
--------------
this is debug: pass by reference  //debug(A);
--------------
call non-copy constructor    //A = Fraction(2,3);---> construct temporary object
call copy assignment operator  //A = Fraction(2,3);
--------------
call copy constructor   //debugPassByValue(A);
this is debug: pass by value
--------------

现在,您将更清楚地了解所谓的内容。

在下文中,我们将[x]视为 x 是可选的。

我对通过引用传递对象和按值传递特定类的函数之间的差异感到困惑。

按值传递对象时,程序必须创建函数的本地对象,因此它调用类的复制构造函数来创建此对象。当您通过引用(似乎通过指针(传递时,函数内部的变量object1只是传递给函数的对象的别名;因此,如果在函数内编辑一个,则编辑也将应用于外部对象。

上述行是否调用默认构造函数来制作临时对象 Fraction(2,3(,然后是赋值运算符?

它是赋值运算符。考虑到A是已经声明的类型X变量,它将被称为X Fraction::operator=([const] Fraction[&])或任何兼容的类型。

注意:当声明Fraction x = Fraction(2, 3)时,它不会像您所期望的那样operator=使用,而是调用相应的构造函数(在本例中为 Fraction::Fraction([const] Fraction[&]) (。

事实上,

debug的情况下,没有制作任何副本。

在第二种情况下,我不太确定我是否理解你的问题。这一行:

A = Fraction(2,3);

应使用 Fraction 的赋值运算符。 A已经存在,因此它使用实例A上的赋值运算符将其分配给临时对象Fraction(2,3)