首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >为什么编译器在这个问题上纠缠我呢?

为什么编译器在这个问题上纠缠我呢?
EN

Stack Overflow用户
提问于 2011-11-02 19:52:43
回答 9查看 1K关注 0票数 17

(使用Visual C++ 2010,在调试中编译,优化已关闭__)

我有以下非常简单的类:

代码语言:javascript
复制
class exampleClass
{
public:
    exampleClass()
    {
        cout << "in the default ctor" << endl;
    }
private:
    exampleClass (const exampleClass& e)
    {
        cout << "in the copy ctor" << endl;
    }
};

当我尝试用下面的main代码编译它时:

代码语言:javascript
复制
#include <iostream>
using namespace std;

int main()
{
    exampleClass e1=exampleClass();
    return 0;
}

我得到了编译错误:

代码语言:javascript
复制
'exampleClass::exampleClass' : cannot access private
                               member declared in class 'exampleClass'

当我从复制ctor中删除访问修饰符"private“时,程序仅编译和打印

代码语言:javascript
复制
in the default ctor

为什么会发生这种情况?如果编译器无论如何都不会调用复制ctor,为什么它会困扰我呢?

由于一些人错过了第一行(至少在一些编辑之前),我将重复它:

在关闭了优化的情况下,我在调试中编译了

EN

回答 9

Stack Overflow用户

回答已采纳

发布于 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。

票数 16
EN

Stack Overflow用户

发布于 2011-11-02 19:54:36

代码语言:javascript
复制
exampleClass e1=exampleClass();

这将首先使用默认构造函数创建一个临时exampleClass,然后使用复制构造函数将其复制到e1中。这将调用私有复制构造函数,因此会给出错误。用默认构造函数实例化一个类的实例的常用方法是:

代码语言:javascript
复制
exampleClass e1;
票数 12
EN

Stack Overflow用户

发布于 2011-11-02 20:01:20

编译器需要在那里对您进行bug。虽然复制可以省略,但标准要求复制构造函数对于该类型的构造是可访问的。当然,您可以简化代码并完全避免复制构造:

代码语言:javascript
复制
exampleClass e1; // Will call exampleClass::exampleClass()
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7979855

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档