Копировать конструктор не называется? - PullRequest
0 голосов
/ 21 июня 2010
class X
{
  int i;  
  public:
  X(int m) : i(m) {};

  X(const X& x)
  {
    //cout "copy constructor is called\n";
  }

  const X opearator++(X& a,int)
  {
     //cout "X++ is called\n";
     X b(a.i);
     a.i++;
     return b;
  }
  void f(X a)
  {   }
};

 int main()
{ 
  X a(1);
  f(a);
  a++; 
  return 0;
}

Здесь, когда вызывается функция 'f', вызывается конструктор копирования, как и ожидалось.В случае ++ вызывается функция operator ++, но когда она возвращает «конструктор копирования не вызывается».почему «конструктор копирования не вызывается при возврате из функции« оператор ++ »?

Ответы [ 6 ]

11 голосов
/ 21 июня 2010

Я полагаю, вы столкнулись с оптимизацией возвращаемого значения (RVO) http://en.wikipedia.org/wiki/Return_value_optimization

7 голосов
/ 21 июня 2010

Известный в Интернете C ++ FAQ Lite (который вы можете найти здесь , например) является обязательным для прочтения для каждого программиста C ++.

Ваш вопрос, вероятно, соответствует этому:
[10.9] Означает ли возврат по значению дополнительные копии и дополнительные издержки?

3 голосов
/ 21 июня 2010

Компилятору разрешается исключать вызов конструктора копирования, когда объект возвращается из функции.

То есть фактически не требуется вызывать конструктор копирования: он может просто создать объект, который должен быть возвращен, в любом месте, куда должен быть возвращен объект из функции.

2 голосов
/ 21 июня 2010

Похоже, RVO (Оптимизация возвращаемого значения). Ваш компилятор видит, что вы ничего не делаете с экземпляром 'b' и с его возвращенной копией, поэтому он удаляет его (операция копирования объекта) из скомпилированного вывода.

0 голосов
/ 11 июля 2014

Ну, у вас было несколько ошибок в вашем коде. Если вы скомпилируете и запустите код, который я прикрепил, вы увидите, что конструктор копирования успешно вызывается при возврате operator ++.

#include <iostream>

class X {
public:
    X(int m) : i(m) {};

    X(const X& x)
    {
        std::cout << "Copy constructor is called\n";
    }

    X
    operator++(int)
    {
        std::cout << "X++ is called\n";

        this->i++;
        return *this;
    }


private:
    int i;

};


void
f(X a)
{
}


int
main(void)
{
    X a(1);
    f(a);
    a++;
    return 0;
}
0 голосов
/ 21 июня 2010

Законно копировать копии, даже если у конструктора копирования есть побочные эффекты.Он называется RVO (есть также один для именованных (комментарий: спасибо) значений, NRVO) и явно разрешен Стандартом.

...