2013-03-25 40 views
1

我在由参考和值到特定类的功能通过对象之间的差异混淆。如果我按值传递对象,我知道默认的拷贝构造函数使得对象的成员由成员副本在给定的功能使用。但是,如果我将对象作为需要深度复制的类的const引用传递,复制构造函数是否仍然被调用?说我有一个功能构造函数调用和物体通过

 void debug(const MyClass& object1); 

会通过object1调用复制构造函数吗?或者是对象直接传递给函数而没有创建副本?还有一个问题 - 如果我有一个叫Fraction-

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

    A = Fraction(2,3); 

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

谢谢。

回答

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

现在你将有什么是所谓的一个更清晰的视野。

1

事实上在debug的情况下,没有副本。

在第二种情况下,我不能肯定我明白你的问题。此行:

A = Fraction(2,3); 

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

+0

对不起,我不是很明确。我真的想知道是否调用构造函数来构造临时对象Fraction(2,3),然后通过默认赋值运算符将其分配给A. – jonnywalkerr 2013-03-25 02:29:14

2

在下文中,我们将考虑[x]意味着x是可选的。

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

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

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

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

注:声明Fraction x = Fraction(2, 3)时,它不会被使用的operator=,你可能期望的,对应的构造将改为调用(在这种情况下Fraction::Fraction([const] Fraction[&]))。

+0

因此,对于我自己的教化,通过引用传递对象或作为函数的const引用不会调用复制构造函数。在任何一种情况下,对象都是别名,唯一的区别是const引用不会是可变的。它是否正确? – jonnywalkerr 2013-03-25 02:31:58

+0

@Jonnywalkerr,是的,这是正确的。实际上'const'引用的'const'部分可以很容易地用'constant_cast'向下转换,但是,它不应该是可变的。 – Shoe 2013-03-25 02:34:57