2011-09-21 142 views
1

我对下面的代码问题:拷贝构造函数和operator =在C++

让我们说我有了一个拷贝构造函数和接收一个字符串值常规构造一类p。

我有以下代码:

P doSomething(){ 
    P p("myValue"); 
    return p; 
} 

int main(){ 
    P m=doSomething(); 
    return 1; 
} 
  1. 为什么不拷贝构造函数在doSomething()函数的调用return p
  2. 通话P m=doSomething() - 它想调用拷贝构造函数或操作=?
  3. 的情况下,这是运营商=,就是这段代码的差异及以下内容:(拷贝构造函数我知道这里的呼叫)

    P new_val=("newVal"); 
    p m=new_val; 
    

谢谢, 玛丽

+0

可能重复[为什么析构函数被调用一次?(http://stackoverflow.com/questions/ 6422114/why-has-the-destructor-been-called-only-once) –

+0

你可以发布你在'class P'中定义的拷贝构造函数的代码吗? – cpx

+0

在初始化一个变量时,即使您正在编写'=',也始终使用复制构造函数。关于为什么它没有在你的例子中使用,可能是编译器优化了你的代码? – Shahbaz

回答

-2

1)为什么复制构造函数在doSomething()函数的“return p”处被调用?

它应该 - 尝试打印一些东西到复制c-tor中的控制台,看它是否真的在运行。

2)调用P m = doSomething() - 它是否假设调用复制构造函数或操作符=?

应拨打运营商=。再次,使用调试消息打印从该方法中的情况下,检查

3)它是操作员=,就是该代码的差和以下: p新=(“的newval”); P M =新; (我知道这里的电话是用于复制构造函数的)

你错过了代码片段的内容吗?我认为它不会编译

+0

你错了...... –

+0

吨应该 - 尝试打印的东西在副本C-TOR控制台,看看它是否真的不多。 - 我做到了,它不显示任何信息 – mary

2
  • 为什么不在doSomething()函数的返回p处调用复制构造函数?

该标准允许删除该副本。谷歌为[N]视网膜静脉阻塞。在某些编译器出现这种情况只有在优化,对别人是调用约定的一部分,因此总是会发生的。

  • 调用P m = doSomething() - 它是否假设调用复制构造函数或操作符=?

T t = x;T t(T(x))“语法糖”(在这个意义上,T(x)隐式地发生),因此具有 - 尽管= - 无关operator=。请注意,这里也将增设临时可以被省略,因此没有拷贝构造函数被调用。

  • 的情况下,这是运营商=,就是这段代码的差异及以下:

这个代码是没有意义的,那你究竟意味着什么?

P new=("newVal"); 
p m=new; 
+0

再点2,它不是相当语法糖:在'T t时的转换= x'是隐式的(和'explicit'构造将不予考虑);重写中的转换是明确的。 (实际上可以编写代码,其中两者都是合法的,但是具有不同的语义,但是这样的代码可能是最好的避免。) –

+0

复制初始化和直接初始化并不完全相同。后者甚至可以使用'显式'拷贝构造函数,前者不会。 –

+0

@JamesKanze:因此,围绕它的引用,我试图使答案有点清楚。 – PlasmaHH

0

我做了一个小样本进行演示。

void print(char* text, int ident) 
{ 
    for(int i = 0 ; i < ident ; i++) 
    { 
     printf(" "); 
    } // end for 

    fprintf(stdout, text); 
    fprintf(stdout, "\n"); 
    fflush(stdout); 
} 

class P 
{ 
public: 
    char* _str; 

    P (P& arg) 
    { 
     print("copy constructor", 2); 
     arg._str = this->_str; 
    } 

    P (char* str) 
    { 
     print("constructor", 2); 
     _str = str; 
    } 
}; 

P doSomething(){ 
    print("do something - function", 1); 
    P p("myValue"); 
    print("before return p", 1); 
    return p; 
} 

int main(int argc, char* argv[]) 
{ 
    print("start", 0); 
    P m=doSomething(); 
    print("stop - call return", 0); 
    return 1; 
} 

这将返回

 
start 
    do something - function 
     constructor 
    before return p 
     copy constructor 
stop - call return 

所以拷贝构造函数会被调用的