a
is declared as a function that returns a MyClass
b
is the normal way to construct with an int parameter
c
is the normal way to construct with no parameters
d
requires an accessible copy (/move)-constructor as technically it copies the temporary on the RHS into d
but the compiler might not actually invoke it.
e
is the same but uses the int constructor. If you did
MyClass e = 0;
that would also require for the constructor that takes an int to be non-explicit.
To answer the question "How does e differ from b". The two objects are alike, but the construction you use with e
would fail to compile if your class did not have an accessible copy/move constructor. (Move constructor in C++11)
b does not appear to declare a function so doesn't fail unlike a.
In C++03 if you put in
class MyClass {
// etc.
private:
MyClass( const MyClass& );
};
The compiler would complain on the lines that create d
and e
In C++11
class MyClass {
// etc.
// this can be public too
MyClass( MyClass&& ) = delete;
};
would invoke a compiler error "use of deleted function" when you try to create d
and e
.
The private copy constructor would also yield the error unless you did:
class MyClass{
public:
MyClass(){
std::cout << "Called Constructer A \n";
}
MyClass(int n){
std::cout << "Called Constructer B \n";
}
MyClass( MyClass const&) = delete; // cannot copy
MyClass( MyClass && ) = default; // but you CAN move
};
Now your code will compile.
Whilst we are on the subject of constructors in C++11, you can also have:
MyClass f{}; // not a function
MyClass g{1};
MyClass h = MyClass{};
MyClass i = MyClass{0};
MyClass j = {};
MyClass k = {0};
Note that if I change my move constructor (currently =default) to
MyClass( MyClass && )
{
std::cout << "Moved\n";
}
I tried it and "Moved" never printed. The compiler can (and did) optimise it away. But it has to be accessible.