Reputation: 469
I wrote a small snippet of C++ code in a main.cpp file and am trying to understand how it's working.
First I defined a class "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;
}
};
Then I executed main:
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;
}
I'm using g++ as my compiler and when I run the following code:
g++ --std=c++11 -fno-elide-constructors -c main.cpp
g++ main.o -o main.exe
./main.exe
Which prints the following:
Creating v = 10
Ctor called
Creating v = 20
Ctor called
I compile the code again, but without the copy constructors getting optimized out:
g++ --std=c++11 -fno-elide-constructors -c main.cpp
g++ main.o -o main.exe
./main.exe
And now, it print the following:
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
Not sure why it's calling the copy constructor so many times. I'm a C++ noob and would like to understand the flow much better. I'm curious to know how this code is running and why the copy constructor is getting called so often.
Upvotes: 1
Views: 54
Reputation: 26975
Read about Return value optimization (RVO). If RVO is off then your copy constructor is getting called very often. If RVO is on then, for example, the code auto v = Value(10);
omits copy ctor calls.
Upvotes: 1
Reputation: 141574
Here are the copies:
auto v = Value(10);
initializes v
using copy-constructor from Value(10)
.auto newValue = Value(v.rawValue() * 2);
initializes newValue
using copy-constructor from Value(v.rawValue()*2)
.return newValue;
initializes the return value using copy-constructor from newValue
.auto v2 = doubleValue(v);
initializes v2
using copy-constructor from the return value.All of these are copy-elision contexts.
Upvotes: 3