2010-06-21 6 views
0
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 ++ вызывается, но когда он возвращает «конструктор копирования не вызывается». почему «копия застройщик не вызывается при возвращении из функции 'оператор ++?конструктор копирования не называется?

+0

Вы спрашиваете *, почему copy contructor не вызывается при возврате из функции 'f' *. Я не понимаю, 'f()' пусто, он ничего не возвращает. –

+2

Всегда спрашивайте ** настоящий ** код при задании вопроса. Поскольку ваш код содержит ошибки, которые мешают ему компилировать, это, очевидно, не тот код, который вы действительно используете. –

+0

@BinaryWorrier: 'f()' не возвращает ничего, кроме 'a ++' does;) –

ответ

3

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

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

0

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

+2

N в NRVO означает «named», а не «новый». –

+0

Достаточно близко: P – Puppy

2

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

+0

b не удаляется. У него просто нет причин копировать. Копирование elision работает путем слияния источника и целевого объекта в один объект. Когда применяется NRVO, b относится к тому же объекту, который возвращает функция. – sellibitze

+0

@sellibitze: Извините за неточное использование местоимений. «Он», который удаляется, - это вызов конструктора копирования. Компилятор не будет полностью оптимизировать объект «b» из-за возможных побочных эффектов конструктора. Эти побочные эффекты не дают слайда, как в RVO. Спасибо за комментарий. –

0

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

#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; 
} 
Смежные вопросы