2011-01-09 90 views
1

如果拷贝构造函数是由private然后在复制构造函数不被调用用于复制初始化或优化?

案例1:没有错误,编译器不一样,如果拷贝构造函数是在类中定义的照顾。

案例2:错误,复制构造函数是私有的,当它被制作为public时,它被省略。

它是否直接优化副本而不会注意到如果构造函数是private

#include <string> 
using std::string; 

class T 
{ 
    string s; 
    T(const T &obj):s(obj.s){} 
public: 
    T(const string &str):s(str){} 
}; 

int main() 
{ 
    T a = ("Copy Initialization");  //Case: 1 

    T b = T("Copy Initialization"); //Case: 2 
} 
+0

在`Case:1`中,实际上并没有创建一个`T`类型的临时对象。你怎么能给它分配``````T`型`? – Mahesh 2011-01-09 14:17:21

回答

5

情况2来下12.8/31 N3225:

如果 复制/移动的构造或复制/移动 赋值操作符的对象的程序是形成不良的是 隐式地使用ODR-并且特殊的 成员函数不可访问。

只是因为抄袭ctor并不意味着它不会被使用。 3.2/2:

一组候选的 功能的ODR使用的,如果它是 通过重载解析选择时 从 潜在评估表达称为的成员。 (注:这包括调用命名为 的函数(5.2.2),操作符 重载(第13章),用户定义的 转换(12.3.2),分配 功能放置新(5.3.4),作为 以及非默认初始化 (8.5)。即使 调用实际上被 实现取消,复制构造函数或移动构造函数也不会使用。末端音符]

当心当然,这是MSVC的不充分 C++ 0X兼容,因为(a)的C++ 0x不是标准的是,并没有最终确定;和(b)无论如何MSVC还没有实施一切。但是这个东西并没有从C++ 03中大幅改变,所以我相信这个解释仍然存在。

第1种情况也会出现这种情况,除了在两个C++ 03编译器上我检查过它没有得到那么多,因为没有可能从字符串文字转换到T.我不能麻烦检查是否有任何额外的转换序列允许在C + + 0x,可能有一个新的条款在任何地方:-)

这仍然是一个谜,为什么MSVC允许案例1有史以来,即使有公共拷贝ctor 。它是否允许严格的C++ 03模式?

2

案例1:没有错误,如果拷贝构造函数是在类中定义的编译器不关心。

T a = ("Copy Initialization");should give an error,因为没有合适的构造从"const char [20]"转换为"T"

你的意思是T a = std::string("Copy Initialization");

它是否直接优化副本而不会注意到如果构造函数是私有的?

不,它不能。编译器通常在代码优化阶段之前执行句法和语义分析。

+0

@ Prasoon在C++ 0x编译器中没有``T``const char [20]`,因为进行了隐式类型转换。 – cpx 2011-01-09 14:23:03

+0

@ Dave18:http://ideone.com/Yij87 – 2011-01-09 14:24:24