【问题标题】:C++ Basic CTOR clarification - why the assignment / copy constructor is not being calledC++ 基本 CTOR 说明 - 为什么不调用赋值/复制构造函数
【发布时间】:2018-10-16 04:41:35
【问题描述】:

下面是我的示例程序:

当我编译并运行以下程序时,我会得到输出:

#include <iostream>
class A 
{
   public:
   explicit  A() 
      {
        std::cout << "A CTOR\n" << std::flush;
      }
    ~A()
      {
         std::cout << "A DTOR\n" << std::flush;
      }
      A(const A & a) 
      {
          std::cout << "A DEEP COPY CTOR\n" << std::flush;
      }
      void operator = (const A & a) 
      {
          std::cout << "A DEEP COPY = CTOR\n" << std::flush;
      }
      A(A && a) 
      {
          std::cout << "A DEEP COPY MOVE CTOR\n" << std::flush;
      }
      void operator = (A && a) 
      {
          std::cout << "A DEEP COPY MOVE = CTOR\n" << std::flush;
      }
};
int main() 
{
 A a = A();
 A b(A());
}

编译并运行二进制文件:

$ c++ -std=c++14 try47.cpp

A CTOR
A DTOR

我期待 A 的默认构造函数将被调用,然后在第一行复制赋值 ctor 并将 ctor 移动到第二行?但这似乎不会发生?为什么?我想我在这里缺少一些基本的理解?

请说明实际调用哪些 CTOR 的时间?

【问题讨论】:

  • 第二行是函数声明,不是变量定义+初始化; b 是一个函数,而不是 A 类型的对象。从概念上讲,第一行是复制初始化——但复制构造函数是elided
  • 我添加了明确的关键字,但仍然是相同的输出
  • 赋值运算符不是构造函数

标签: c++ c++11


【解决方案1】:

不要让= 运算符让您失望。第一行发生的只是一个默认的构造函数调用。不需要复制分配(编译器省略了这一点),因为您没有将任何内容分配给a

但以下将导致您正在寻找的内容:

 A a, c; //A CTOR
 c = a; //A DEEP COPY = CTOR because c is being assigned the value of a

第二行只是一个函数声明。

A b(A());

b 是一个以A 为参数并返回A 的函数。这种歧义通常被称为最令人头疼的解析。

CPP 标准草案 (N4713) 指出:

9.8 歧义分辨率 [stmt.ambig]

  1. 在涉及表达式语句和声明的语法中存在歧义:将函数样式显式类型转换作为其最左侧子表达式的表达式语句与第一个声明符以 (. 在这些情况下,声明就是声明。

  2. [ 注意:如果语句在语法上不能是声明,则不存在歧义,因此该规则不适用。可能需要检查整个语句以确定是否是这种情况。

【讨论】:

  • 因为line2是一个函数声明,而不是A的实例化。请看答案的第二部分。
  • 谢谢 - 如果有任何调用 CTOR 的进一步规则,您能否提供 - 这将非常有帮助 - 同样是因为我们应该写的 CTOR 是什么 - 小心 - 因为否则我们会建立一个大类对象,无论是浅的还是深的,都会被默默地复制
  • Scott Meyers 的《Effective C++》对此有一整章。这是那本书的第2章。很好解释。您的图书馆应该有一份副本。
猜你喜欢
  • 1970-01-01
  • 2012-02-28
  • 2014-08-14
  • 1970-01-01
  • 2012-02-12
  • 1970-01-01
  • 1970-01-01
  • 2021-02-18
  • 2014-01-14
相关资源
最近更新 更多