【问题标题】:C++ Special member functionsC++ 特殊成员函数
【发布时间】:2015-03-01 14:07:51
【问题描述】:

我一直都知道C++的特殊成员函数有:

  • 默认构造函数
  • 复制构造函数
  • 复制赋值运算符
  • 析构函数
  • 移动构造函数
  • 移动赋值运算符

现在我正在阅读 Meyers Effective C++ 书籍,并意识到还有一对 address-of 运算符

我可以这样重新定义它:

class A
{
public:
  A* operator&()
  {
    std::cout << "Address of operator" << std::endl;
  }
};

int main()
{
  A a;
  B* b = &a; // Will call address-of operator.
}

为什么在 C++ 标准第 12 节(特殊成员函数)中没有关于此运算符的字样。

【问题讨论】:

  • 可能是因为它不被视为一个特殊成员函数,而是一个operator,并且包含在该部分中?
  • πάντα ῥεῖ 复制赋值运算符也是运算符,但定义明确
  • “这也是C++面试中常见的问题。”我不这么认为...
  • @VladfromMoscow:我不想为一家希望我熟记 C++ 标准的章节编号的公司工作。如果他们在面试时带了一份标准的副本并想讨论其中的一部分,那就够公平了。

标签: c++ c++11 assignment-operator default-constructor


【解决方案1】:

这应该是一个答案,而不是评论,就这样吧:

这是您的 Effective C++ 版本中的一个错误。我的副本说:

如果您不自己声明它们,您深思熟虑的编译器会 声明他们自己版本的复制构造函数,赋值 运算符和析构函数。

如您所见,不再提及任何地址运算符。 errata for the second edition 明确提到了这一变化:

声明没有操作符和函数的类没有它们 隐式声明。相反,编译器使用内置的地址 每当“&”应用于该类型的对象时,运算符。这 反过来,行为在技术上并不是一个全球性的应用 运算符&函数。相反,它是使用内置运算符。

【讨论】:

    【解决方案2】:

    “为什么在 C++ 标准第 12 节(特殊成员函数)中没有关于此运算符的字样。”

    因为这个操作符不是一个特殊的成员函数。它实际上覆盖在this section

    13.5 重载的运算符
    1 具有以下运算符函数 ID 之一作为其名称的函数声明声明了一个运算符 功能。一个函数模板声明,其名称为以下操作符函数 ID 之一 声明一个运算符函数模板。运算符函数模板的特化也是运算符 功能。操作符函数被称为实现其
    中命名的操作符 操作员函数 ID。

    operator-function-id:
    operator operator
    operator: one of
    
    new delete new[] delete[]
    + - * / % ˆ & | ∼
    ! = < > += -= *= /= %=
    ˆ= &= |= << >> >>= <<= == !=
    <= >= && || ++ -- , ->* ->
    ( ) [ ]
    

    ...

    2 一元和二元形式 +-*&amp; 可以重载。

    【讨论】:

      【解决方案3】:

      如果您更仔细地阅读标准,您会发现特殊成员函数是那些编译器可以隐式声明的函数,如果您不显式声明它们。

      来自 C++ 标准:

      12 特殊成员函数 [special] 1 默认构造函数 (12.1)、复制构造函数和复制赋值运算符 (12.8)、移动 构造函数和移动赋值运算符 (12.8) 和析构函数 (12.4) 是特殊的成员函数。 [注:实施将 为某些类类型隐式声明这些成员函数 程序没有明确声明它们。 实现 如果它们被 odr-used (3.2),将隐式定义它们。见 12.1、12.4 和 12.8。 ——尾注]隐式声明的特殊成员函数 在类说明符的结束 } 处声明。节目应 不定义隐式声明的特殊成员函数。

      顺便说一句,您显示的运算符的定义是错误的,因为它什么也不返回。

      至于其他成员函数,包括例如应声明为类成员的运算符,则实现不会隐式声明它们。由程序员决定是否声明一些操作符。例如,您的类可能包含十几个赋值运算符。

      【讨论】:

      • 我仔细阅读了这部分。所以从你的回答我可以假设如果我没有明确声明地址运算符程序不会隐式声明它?在这种情况下,为什么 Meyers 会写 - 如果您自己不声明它们,您深思熟虑的编译器将声明它们自己版本的复制构造函数、赋值运算符、析构函数和一对地址运算符?
      • @Ashot Khachatryan 我已经引用了标准中关于特殊成员函数的引用。引用中有什么不清楚的地方?您在哪里看到实现将隐式声明地址运算符?
      • 引用标准 - “当程序没有显式声明它们时,实现将为某些类类型隐式声明这些成员函数。”那么请回答这个问题:如果我没有显式声明,地址操作符会被隐式声明吗?
      • 我读得很仔细,对我来说很清楚就像1 + 1,你能回答我问的问题吗?
      • @Ashot Khachatryan Ashot 在引用中列出了实现隐式声明的函数,如果您不自己显式声明它们。你在哪里看到过地址操作符?
      猜你喜欢
      • 2011-03-17
      • 2012-07-25
      • 2012-10-14
      • 1970-01-01
      • 2015-03-04
      • 2012-01-27
      • 2016-06-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多