Understanding Copy Constructor Elision and Return Value Optimization in C++
During copy initialization (using the equals sign), compilers may bypass copy or move constructors and create objects directly. This optimizatino is permitted but not required by the standard.
std::string book_id = "123";
// Can be rewritten as:
std::string book_id("123");
In this case, the compiler might skip creating a temporary string object and copying it, instead constructing the object directly.
Consider this example demonstrating Return Value Optimization (RVO):
class Employee {
public:
Employee() {
std::cout << "Default constructor at " << this << std::endl;
}
Employee(const Employee& e) {
std::cout << "Copy constructor at " << this << std::endl;
}
~Employee() {
std::cout << "Destructor at " << this << std::endl;
}
};
Employee createEmployee() {
Employee emp;
return emp;
}
void demo() {
Employee e = createEmployee();
}
When executed, only the default constructor and destructor calls appear, showing the compiler optimized away both:
- The temporary object creation during return
- The copy construction during initialization
Another case where copy construction occurs is during pass-by-value:
void processEmployee(Employee e) {
// Function body
}
int main() {
Employee emp;
processEmployee(emp); // Copy constructor invoked here
return 0;
}
This demonstrates mandatory copy construction when passing objects by value, unlike the optimizable cases shown earlier.