简体   繁体   English

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

[英]Constructor calls during assignment operations and object passing

I am confused over the differences between passing objects by reference and by value to functions of a particular class. 我对按引用和按值传递对象到特定类的函数之间的区别感到困惑。 If I pass objects by value, I know that the default copy constructor makes a member-by-member copy of the the object for use in the given function. 如果我按值传递对象,则我知道默认的复制构造函数将使该对象的成员逐个成员复制,以供在给定函数中使用。 However, if I am passing objects as a const reference for a class that requires deep copy, is the copy constructor still called? 但是,如果我将对象作为需要深层复制的类的const引用传递,则仍会调用复制构造函数吗? Say that I had a function 说我有功能

     void debug(const MyClass& object1); 

Would passing object1 call the copy constructor? 传递object1会调用复制构造函数吗? Or is the object passed into the function directly without having a copy made? 还是将对象直接传递给函数而不进行复制? One more question - If I have a class called Fraction- 还有一个问题-如果我有一个叫做Fraction的课程,

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

     A = Fraction(2,3);

Does the aforementioned line call the default constructor to make a temporary object Fraction(2,3) and then the assignment operator? 前面提到的行是否调用默认构造函数来创建一个临时对象Fraction(2,3),然后创建赋值运算符?

Thanks. 谢谢。

In the following we will consider [x] to mean that x is optional. 在下文中,我们将考虑[x]表示x是可选的。

I am confused over the differences between passing objects by reference and by value to functions of a particular class. 我对按引用和按值传递对象到特定类的函数之间的区别感到困惑。

When you pass an object by value, the program must create the local object of the function therefore it calls the copy constructor of the class to create this object. 当按值传递对象时,程序必须创建函数的本地对象,因此它调用类的副本构造函数来创建此对象。 When you pass by reference (and seemingly by pointer) the variable object1 inside the function is just an alias of the object you passed to the function; 当您通过引用(似乎是通过指针)传递时,函数内部的变量object1只是传递给函数的对象的别名; therefore if you edit the one inside the function, the edits will be applied to the outside object as well. 因此,如果您在函数内部进行编辑,则所做的编辑也将应用于外部对象。

Does the aforementioned line call the default constructor to make a temporary object Fraction(2,3) and then the assignment operator? 前面提到的行是否调用默认构造函数来创建一个临时对象Fraction(2,3),然后创建赋值运算符?

It's the assignment operator. 它是赋值运算符。 Considering A to be an already declared variable of type X it will be called X Fraction::operator=([const] Fraction[&]) or any compatible type. 假设A是已经声明的类型X变量,它将被称为X Fraction::operator=([const] Fraction[&])或任何兼容的类型。

Notice: when declaring Fraction x = Fraction(2, 3) it won't be used the operator= as you may expect, the corresponding constructor will be called instead (in this case Fraction::Fraction([const] Fraction[&]) ). 注意:当声明Fraction x = Fraction(2, 3) ,不会像您期望的那样使用operator= ,而是会调用相应的构造函数(在这种情况下, Fraction::Fraction([const] Fraction[&]) )。

Would passing object1 call the copy constructor?

No, it will not call the copy constructor since passed by reference No copy is made in this case 不,由于通过引用传递,因此它不会调用复制构造函数,在这种情况下不进行复制

A = Fraction(2,3);

Yes, it will call the constructor with two parameters (or default constructor if both parameters have default values), then call the copy assignment operator. 是的,它将使用两个参数调用构造函数(如果两个参数都具有默认值,则调用默认构造函数),然后调用副本分配运算符。

You can see the output from code below: 您可以从下面的代码中看到输出:

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

} }

You will see the following output: 您将看到以下输出:

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

Now you will have a clearer view of what are called. 现在,您将更清楚地了解所谓的内容。

Indeed in the case of debug no copy is made. 实际上,在debug的情况下,不会进行任何复制。

In the second case, I'm not quite sure I understand your question. 在第二种情况下,我不确定我是否理解您的问题。 This line: 这行:

A = Fraction(2,3);

Should use Fraction 's assignment operator. 应该使用Fraction的赋值运算符。 A already exists, so it uses the assignment operator on instance A to assign it Fraction(2,3) which is a temporary object. A已经存在,因此它使用实例A上的赋值运算符为它分配作为临时对象的Fraction(2,3)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM