我正在读复制和交换

我试着阅读复制省略一些链接,但无法弄清楚正确的是什么意思。可有人请解释一下这种优化是什么,尤其是下面的文字是什么平均值

  

这不仅是一个方便,但实际上是一个优化问题。如果参数(一个或多个)结合到左值(另一非const对象)时,对象的副本,同时创建参数(多个)自动进行的。然而,当s结合到右值(临时对象,文字),复制通常消隐,其保存到一个复制构造函数和析构函数的调用。在参数被接受为const引用赋值运算符的早期版本,复制省略不参考结合时,发生在一个右值。正在建立这个结果转换成一个附加的目的和销毁。

有帮助吗?

解决方案

拷贝构造的存在是为了进行复印。从理论上讲,当你写这样一行:

CLASS c(foo());

,编译器将必须调用拷贝构造复制foo()返回到c

复制省略是跳过调用拷贝构造以便不支付的开销的技术。

例如,编译器可以安排foo()将直接构建其返回值放入c

下面是另一个例子。比方说,你有一个函数:

void doit(CLASS c);

如果您有一个实际的参数调用它,编译器调用拷贝构造函数使原来的参数不能被修改:

CLASS c1;
doit(c1);

但现在考虑一个不同的例子,假设你打电话给你的功能是这样的:

doit(c1 + c1);

operator+将不得不创建临时对象(一个rvalue)。而不是调用doit()之前调用复制构造的,编译器可以通过将其通过operator+创建的临时和传递而不是doit()

其他提示

下面是一个例子:

#include <vector>
#include <climits>

class BigCounter {
 public:
   BigCounter &operator =(BigCounter b) {
      swap(b);
      return *this;
   }

   BigCounter next() const;

   void swap(BigCounter &b) {
      vals_.swap(b);
   }

 private:
   typedef ::std::vector<unsigned int> valvec_t;
   valvec_t vals_;
};

BigCounter BigCounter::next() const
{
   BigCounter newcounter(*this);
   unsigned int carry = 1;
   for (valvec_t::iterator i = newcounter.vals_.begin();
        carry > 0 && i != newcounter.vals_.end();
        ++i)
   {
      if (*i <= (UINT_MAX - carry)) {
         *i += carry;
      } else {
         *i += carry;
         carry = 1;
      }
   }
   if (carry > 0) {
      newcounter.vals_.push_back(carry);
   }
   return newcounter;
}

void someFunction()
{
    BigCounter loopcount;
    while (true) {
       loopcount = loopcount.next();
    }
}

在从复制省略somefunction线loopcount = loopcount.next();好处很大。如果复制省略不允许,该行需要拷贝构造函数和析构函数相关的调用3所调用。用被允许复制省略,它可以降低到1个呼叫拷贝构造的,BigCount::next()的明确一个内部其中newcounter被声明。

如果operator =已经声明和定义是这样的:

BigCounter &BigCounter::operator =(const BigCounter &b) {
   BigCounter tmp(b);
   swap(tmp);
   return *this;
}

有能有我们一直拷贝构造函数的调用2,即使复制省略。一,构建newcounterde和其他构建tmpde。而如果没有复制省略仍然会有3.这就是为什么宣布operator =所以它的参数需要调用拷贝构造可以优化使用的赋值运算符“复制和交换”成语时。当复制构造函数被调用用于构建一个参数,它的调用可以被省略,但如果它被调用以创建一个局部变量,它可能不是。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top