In the book Generic Programming and the STL (Chinese edition), it says:
X x = X()
will call the copy constructor.
It seems a little weird to me. And I write a test program like this
#include <iostream>
class Test {
public:
Test() {
std::cout << "This is ctor\n";
}
Test(const Test&) {
std::cout << "This is copy-ctor\n";
}
};
int main(int argc, char** argv)
{
Test t = Test();
return 0;
}
The output is "This is ctor". ok, now I'm confused, which is right?
A user-defined copy constructor is generally needed when an object owns pointers or non-shareable references, such as to a file, in which case a destructor and an assignment operator should also be written (see Rule of three).
The copy constructor is used to initialize the members of a newly created object by copying the members of an already existing object. 2. Copy constructor takes a reference to an object of the same class as an argument.
Nomimally yes, a temporary is default-constructed, and then the copy constructor is invoked to copy it into your object t
.
However, in practice the copy can be optimised out — even though it has side effects (the console output):
[n3290: 8.5/16]
: [..] In certain cases, an implementation is permitted to eliminate the copying inherent in this direct-initialization by constructing the intermediate result directly into the object being initialized; see 12.2, 12.8.
And (in conjunction with the example given in the same clause):
[n3290: 12.2/2]
: [..] An implementation might use a temporary in which to construct X(2) before passing it to f() usingX
’s copy constructor; alternatively,X(2)
might be constructed in the space used to hold the argument. [..]
But the copy constructor does still have to exist, even though it might not be invoked.
Anyway, if you compile with optimisations turned off (or, with GCC, possibly -fno-elide-constructors
), you will see:
This is ctor
This is copy-ctor
In theory, X x = X()
will call the default constructor to create a temporary object, and copy that into x
using the copy constructor.
In practice, compilers are allowed to skip the copy construction part and default-construct x
directly (which, as David points out in his comment, still requires the copy constructor to be syntactically accessible, though). Most compilers do that at least when optimizations are enabled.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With