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

How do implicitly declared (object level) member functions work according to the ISO C++11 standard?

本文关键字:何根 ISO C++11 工作 标准 函数 成员 声明 对象      更新时间:2023-10-16

这些类定义是等效的吗?

第一个定义:

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 的所有成员函数?

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

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

。来自 C++14 的标准草案 n3797(我相信它与主要标准没有太大区别(。

简而言之,在特殊成员函数中,以默认构造函数为例,我们从本节中看到:(重点是我的(

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

以上并不完全适用于您的代码,但是,进一步的支持证据在某处

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

检查一下你自己,还有更多的支持证据......因此,在标准的意义上,一旦显式定义了任何特殊成员函数,它就与编译器将创建的内容及其相关假设不同。

但归根结底,代码生成器可能会生成相同的代码。只是编译器在编译期间的假设可能不同。

TLDR;

在标准(草案(中还有很多其他段落,它区分了隐式定义的特殊成员函数的效果和它的反面(它对此大多保持沉默(。您可以选择标准并搜索短语"隐式定义"的所有出现

次数