2

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

     void debug(const MyClass& object1); 

传递 object1 会调用复制构造函数吗?还是直接将对象传递给函数而不进行复制?还有一个问题——如果我有一个名为 Fraction 的课程——

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

     A = Fraction(2,3);

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

谢谢。

4

3 回答 3

2

在下文中,我们将考虑[x]表示 x 是可选的。

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

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

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

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

注意:当声明Fraction x = Fraction(2, 3)它不会operator=像你期望的那样被使用时,将调用相应的构造函数(在这种情况下Fraction::Fraction([const] Fraction[&]))。

于 2013-03-25T02:22:01.003 回答
2

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
--------------

现在您将对所谓的内容有更清晰的认识。

于 2013-03-25T02:23:27.810 回答
1

事实上,在debug没有复制的情况下。

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

A = Fraction(2,3);

应该使用Fraction' 赋值运算符。A已经存在,所以它使用实例上的赋值运算符A来分配它Fraction(2,3),它是一个临时对象。

于 2013-03-25T02:06:46.623 回答