2016-10-15 5 views
1

Я написал небольшой фрагмент кода на C++ в файле main.cpp и пытаюсь понять, как он работает.Где вызывается вызов конструктора?

Сначала я определил класс "Value":

#include <algorithm> 
#include <iostream> 

using namespace std; 

class Value { 

    int v; 

public: 

    Value(int v): v(v) { 
    cout << "Ctor called" << endl; 
    } 

    Value(const Value &rhs): v(rhs.v) { 
    cout << "Copy Ctor called. V = " << v << endl; 
    } 

    Value& operator =(const Value &rhs) { 
    cout << "Assignment called" << endl; 
    if (this != &rhs) { 
     auto tmp = Value(rhs); 
     swap(v, tmp.v); 
    } 
    return *this; 
    } 

    int rawValue() const { 
    return v; 
    } 

}; 

Тогда я выполнил главный:

Value doubleValue(const Value &v) { 
    auto newValue = Value(v.rawValue() * 2); 
    return newValue; 
} 

int main() { 
    cout << "Creating v = 10" << endl; 
    auto v = Value(10); 

    cout << "Creating v = 20" << endl; 
    auto v2 = doubleValue(v); 

    return 0; 
} 

Я использую г ++ как мой компилятор и когда я запускаю следующий код:

g++ --std=c++11 -fno-elide-constructors -c main.cpp 
g++ main.o -o main.exe 
./main.exe 

Который печатает следующее:

Creating v = 10 
Ctor called 
Creating v = 20 
Ctor called 

компилировать код еще раз, но без копирования Конструкторы получения оптимизированными:

g++ --std=c++11 -fno-elide-constructors -c main.cpp 
g++ main.o -o main.exe 
./main.exe 

И теперь, распечатать следующее:

Creating v = 10 
Ctor called 
Copy Ctor called. V = 10 
Creating v = 20 
Ctor called 
Copy Ctor called. V = 20 
Copy Ctor called. V = 20 
Copy Ctor called. V = 20 

Не уверен, почему это вызов конструктора копирования так много раз. Я C++ noob и хотел бы лучше понимать поток. Мне любопытно узнать, как работает этот код и почему так часто вызывает вызов конструктора копии.

ответ

3

Вот копии:

  • auto v = Value(10); инициализирует v с помощью копирования-конструктор из Value(10).
  • auto newValue = Value(v.rawValue() * 2); Инициализирует newValue используя copy-constructor от Value(v.rawValue()*2).
  • return newValue; инициализирует возвращаемое значение с использованием copy-constructor от newValue.
  • auto v2 = doubleValue(v); инициализирует v2 с использованием копировального аппарата от возвращаемое значение.

Все это контексты копирования-разрешения.

1

Подробнее о Return value optimization (RVO). Если RVO выключен, ваш конструктор копирования вызывается очень часто. Если RVO включен, то, например, код auto v = Value(10); опускает копии вызовов ctor.