下面是我的示例程序:
当我编译并运行以下程序时,我得到输出:
#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?
答案 0 :(得分:2)
不要让=
运算符让您失望。第一行中发生的只是默认的构造函数调用。无需进行复制分配(编译器无需执行此操作),因为您没有为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]
语法中涉及表达式语句和声明的模棱两可:具有函数式显式类型转换的表达式语句的最左边子表达式可以与第一个声明符以(。开头)的声明区分开。 在这种情况下,声明是声明。
[注意:如果该语句不能在语法上成为声明,则不会有歧义,因此该规则不适用。可能需要检查整个语句以确定是否是这种情况。