隐式声明(对象级别)成员函数如何根据ISO C ++ 11标准工作?

时间:2016-02-07 16:57:20

标签: c++ c++11

这些类定义是否相同?

第一个定义:

class A
{
    std::string s;
};

第二个定义:

class A
{
    std::string s;
public:
    A() : s() {  }
    ~A(){  }
    A(const A& AA) : s(AA.s) {  }
    A(A&& a) noexcept : s(std::move(a.s)) {  }
    A& operator=(const A& AA){
        s=AA.s;
        return *this;
    }
    A& operator=(A&& a) noexcept{
        s=(std::move(a.s));
        return *this;
    }
    const A* operator&() const{ return this; }
    A* operator&(){ return this; }
};

如果不是,你能告诉我一个等同于第一个的类定义,并明确定义了A类的所有成员函数吗?

1 个答案:

答案 0 :(得分:2)

这取决于您对" 等效"的定义。

  • 代码生成的汇编输出? ,对于一个好的编译器和优化器,它们应该是。 : - )
  • 编译器在生成AST并进行类表示或中间代码时的假设? ,为什么?

...来自C++14's standard draft n3797(我相信它与主要标准不同)..

为简单起见,在特殊成员函数中,以一个默认构造函数为例,我们从本节看到:(强调是我的)

  

12.1.5: ....在隐式定义类的默认默认构造函数之前,所有非用户提供的默认构造函数   对于它的基类及其非静态数据成员应该是   隐式定义。 [注意:隐式声明的默认值   构造函数有一个异常规范。明确违约   定义可能具有隐式异常规范,请参见8.4。    - 尾注]

上述内容并不完全适用于您的代码,但是,进一步支持证据的地方

  

12.6.3:非显式复制/移动构造函数是转换构造函数。 隐式声明的复制/移动构造函数是显式构造函数;可以调用隐式类型转换。

检查你自己,还有更多的支持证据 ......所以,在标准意义上,一旦你明确定义了任何特殊的成员函数,它就不同于编译器会创造及其相关的假设。

但是在一天结束时,代码生成器可能会生成相同的代码。 :-)。只是编译期间编译器的假设可能不同。

<强> TLDR;

标准(草案)中还有很多其他段落,它区分了隐式定义的特殊成员函数的效果和它的相反(它基本上是沉默的)。您可以选择标准并搜索所有出现的短语&#34;隐式定义&#34;