8.5.1 避免不必要的复制操作(2)
此示例产生如下输出:
- Constructor called.
- Constructor called.
- Constructor called.
- Executing: motto3 = motto1 + motto2
- Add operator function called.
- Constructor called.
- Copy constructor called.
- Destructor called.
- Assignment operator function called.
- Destructor called.
- Done!!
- Executing: motto3motto3 = motto3 + motto1 + motto2
- Add operator function called.
- Constructor called.
- Copy constructor called.
- Destructor called.
- Add operator function called.
- Constructor called.
- Copy constructor called.
- Destructor called.
- Assignment operator function called.
- Destructor called.
- Destructor called.
- Done!!
- motto3 contains -
- The devil takes care of his own. If you sup with the devil use a long spoon.
- The devil takes care of his own. If you sup with the devil use a long spoon.
- Destructor called.
- Destructor called.
- Destructor called.
示例说明
我们感兴趣的第一条语句是:
- motto3 = motto1 + motto2; // Use new addition operator
这条语句调用operator+()将motto1和motto2相加,此运算符函数调用构造函数来创建要返回的临时对象。然后,复制构造函数复制返回的对象,可以从析构函数调用中看到,析构函数销毁了此返回对象。然后operator=()函数将副本复制到motto3中。最后,通过调用析构函数,销毁作为赋值操作右操作数的临时对象。这条语句导致了两个复制临时对象(rvalue)的操作。
我们感兴趣的第二条语句是:
- motto3motto3 = motto3 + motto1 + motto2;
首先调用operator+()函数连接motto3和motto1,此运算符函数调用构造函数来创建要返回的对象。然后使用复制构造函数来复制返回的对象,在析构函数销毁函数中创建的原始对象之后,通过再一次调用operator+()函数,连接副本与motto2,重复执行函数调用序列。最后,调用operator=()函数来存储结果。因此对于这条简单的语句,有3个临时对象复制操作,两个操作来自复制构造函数调用,一个操作来自赋值运算符。
如果CMessage是一个十分复杂的大对象,那么所有这些复制操作在运行时间方面是非常昂贵的。如果可以避免这些复制操作,就可以大大地提高执行效率。我们来看看如何能够做到这一点。