3

我是 C++ 的初学者,我使用的资源表明以下语句d3 = d1 + d2; 调用以下内容:

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

我不明白为什么在将结果分配给先前声明的变量时调用复制构造函数以及为什么调用 2 个构造函数。

运营商如下:

date& date::operator=(const date& other)
{
cout << "Date assignment op" << endl;
    if (this!=&other){
        day=other.day;
        month=other.month;
        year=other.year;
    }
    return *this;
}

date date::operator+(const date& other) const
{
    cout << "Date Operator + called" << endl;
    date temp;
    temp.day=day+other.day;
    temp.month=month+other.month;
    temp.year=year+other.year;
    return temp;
}
4

5 回答 5

8

该表达式(d1 + d2)在从 operator+ ( return temp) 返回时产生一个临时对象。从“temp”创建临时是通过复制构造函数完成的。然后将其分配给 d3。

于 2013-01-24T07:24:13.173 回答
2

当它计算 d1+d2 时,结果是一个临时对象。为了将一个对象分配给另一个对象,正在调用复制构造函数。

于 2013-01-24T07:23:59.313 回答
1

默认情况下,按值return'ing 对象将从源对象复制构造一个临时对象,然后将该临时对象传递给调用者。换句话说,语句d3 = d1 + d2;基本上是这样做的:

date implicit_temp(operator+(d1, d2));
d3 = implicit_temp;

这在幕后分解为以下逻辑:

// The + operator 
date temp; // The default constructor
temp.day = d1.day + d2.day;
temp.month = d1.month + d2.month;
temp.year = d1.year + d2.year;
// return temp;
date implicit_temp(temp); // The copy constructor
temp.~date(); // Destructor
// Assignment operator
d3.day = implicit_temp.day;
d3.month = implicit_temp.month;
d3.year = implicit_temp.year;
implicit_temp.~date(); // Destructor

它与您看到的输出顺序相同。

如果编译器支持 RVO(返回值优化),它将能够优化语句date创建的临时对象,通过传递一个隐藏参数,因此可以通过其运算符直接分配变量,使代码行为好像它是这样写的:returnd3returntempd3=

void date::operator+(const date& other, date& result) const
{
    date temp;
    temp.day=day+other.day;
    temp.month=month+other.month;
    temp.year=year+other.year;
    result = temp;
}

这将在引擎盖下分解为这个逻辑:

// The + operator 
date temp; // The default constructor
temp.day = d1.day + d2.day;
temp.month = d1.month + d2.month;
temp.year = d1.year + d2.year;
// return temp; - Assignment operator
d3.day = temp.day;
d3.month = temp.month;
d3.year = temp.year;
temp.~date(); // Destructor
于 2013-01-24T10:41:01.997 回答
0

在以下情况下调用复制构造函数:

A a=b,
when you return an object,
when you pass an object.

您的+运算符重载函数返回一个临时对象。它实际上将调用一个复制构造函数。

于 2013-01-24T07:22:08.413 回答
0

不要依赖那个

从技术上讲,您的块中operator+有一个temp变量,该变量必须在其外部传递到一个临时对象中,以便稍后提供给您的operator=.

换句话说,你operator=看到的参数不是tempinside operator+,而是它的一个副本,它必须比+块活得更长,才能让它=发生。

但是,如果有:

  • +只有一个 return 语句(实际上有)
  • +所有返回语句总是返回同一个对象

编译器可以通过将临时局部变量与分配中使用的临时变量合并来优化返回时的复制,并完全省略副本。

这是极少数可以消除副作用的优化之一(参见 C++03 的 §12.8.15 或 C++11 的 12.8.31)。

是否调用复制构造函数的事实最终取决于编译器和所需的优化级别。

(感谢juanchopanza的所有澄清)。

于 2013-01-24T08:35:29.913 回答