(使用Visual C++ 2010,在调试中编译,优化已关闭__)
我有以下非常简单的类:
class exampleClass
{
public:
exampleClass()
{
cout << "in the default ctor" << endl;
}
private:
exampleClass (const exampleClass& e)
{
cout << "in the copy ctor" << endl;
}
};
当我尝试用下面的main代码编译它时:
#include <iostream>
using namespace std;
int main()
{
exampleClass e1=exampleClass();
return 0;
}
我得到了编译错误:
'exampleClass::exampleClass' : cannot access private
member declared in class 'exampleClass'
当我从复制ctor中删除访问修饰符"private“时,程序仅编译和打印
in the default ctor
为什么会发生这种情况?如果编译器无论如何都不会调用复制ctor,为什么它会困扰我呢?
由于一些人错过了第一行(至少在一些编辑之前),我将重复它:
在关闭了优化的情况下,我在调试中编译了。
发布于 2011-11-02 20:11:05
这种类型的初始化称为复制初始化。我相信C++11标准中的以下条款适用于这里(第204页,第8.5.16段):
如果初始化是直接初始化,或者如果是复制初始化,其中源类型的cv非限定版本与目标的类相同,或者是目标的类的派生类,则考虑构造函数,则为
。枚举适用的构造函数(13.3.1.3),并通过重载解析(13.3)选择最佳构造函数。调用如此选定的构造函数来初始化对象,并将初始化器表达式或表达式列表作为其参数。如果没有应用任何构造函数,或者重载解决方案不明确,则初始化的格式不正确。
在这种情况下,最合适的构造函数是复制ctor,它是私有的,因此出现错误消息。
为了进一步回答您的问题,当复制ctor是私有的时,由于标准强加的规则,您的程序根本不允许通过编译器检查。当您将复制ctor设置为公共时,程序将变得有效,但对复制ctor的调用将被优化。
编辑:好的,对前面的段落进行详细说明。您在这里处理的是所谓的copy elision。虽然在这种情况下复制省略是可能的,但标准要求您为您的类提供一个可访问的复制ctor。
发布于 2011-11-02 19:54:36
exampleClass e1=exampleClass();
这将首先使用默认构造函数创建一个临时exampleClass
,然后使用复制构造函数将其复制到e1
中。这将调用私有复制构造函数,因此会给出错误。用默认构造函数实例化一个类的实例的常用方法是:
exampleClass e1;
发布于 2011-11-02 20:01:20
编译器需要在那里对您进行bug。虽然复制可以省略,但标准要求复制构造函数对于该类型的构造是可访问的。当然,您可以简化代码并完全避免复制构造:
exampleClass e1; // Will call exampleClass::exampleClass()
https://stackoverflow.com/questions/7979855
复制相似问题