#c #g #copy-constructor
#c #g #копировать-конструктор
Вопрос:
Я написал небольшой фрагмент кода на C в main.cpp файл и я пытаюсь понять, как это работает.
Сначала я определил класс «Значение».:
#include <algorithm>
#include <iostream>
using namespace std;
class Value {
int v;
public:
Value(int v): v(v) {
cout << "Ctor called" << endl;
}
Value(const Value amp;rhs): v(rhs.v) {
cout << "Copy Ctor called. V = " << v << endl;
}
Valueamp; operator =(const Value amp;rhs) {
cout << "Assignment called" << endl;
if (this != amp;rhs) {
auto tmp = Value(rhs);
swap(v, tmp.v);
}
return *this;
}
int rawValue() const {
return v;
}
};
Затем я выполнил main:
Value doubleValue(const Value amp;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 в качестве своего компилятора, и когда я запускаю следующий код:
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 и хотел бы лучше понять процесс. Мне любопытно узнать, как выполняется этот код и почему конструктор копирования вызывается так часто.
Ответ №1:
Вот копии:
auto v = Value(10);
инициализируетсяv
с помощью copy-constructor fromValue(10)
.auto newValue = Value(v.rawValue() * 2);
инициализируетсяnewValue
с помощью copy-constructor fromValue(v.rawValue()*2)
.return newValue;
инициализирует возвращаемое значение с помощью copy-constructor fromnewValue
.auto v2 = doubleValue(v);
инициализируетсяv2
с помощью copy-constructor из возвращаемого значения.
Все это контексты копирования-исключения.
Ответ №2:
Прочитайте об оптимизации возвращаемого значения (RVO). Если RVO отключен, то ваш конструктор копирования вызывается очень часто. Если включен RVO, то, например, код auto v = Value(10);
пропускает вызовы copy ctor.