How Many default methods does a class have?
Sorry, this might seem simple, but somebody asked me this, and I do开发者_Go百科n't know for certain.
An empty C++ class comes with what functions?
Constructor, Copy Constructor, Assignment, Destructor?
Is that it? Or are there more?
In C++03 there are 4:
Default constructor: Declared only if no user-defined constructor is declared. Defined when used
Copy constructor - declared only if the user hasn't declared one. Defined if used
Copy-assignment operator same as above
Destructor same as above
In C++11 there are two more:
- Move constructor
- Move-assignment operator
It is also possible that the compiler won't be able to generate some of them. For example, if the class contains, for example, a reference (or anything else that cannot be copy-assigned), then the compiler won't be able to generate a copy-assignment operator for you. For more information read this
If I define the following class
class X
{};
The compiler will define the following methods:
X::X() {} // Default constructor. It takes zero arguments (hence default).
X::~X() {} // Destructor
X::X(X const& rhs) {}; // Copy constructor
X& operator=(X const& rhs)
{return *this;} // Assignment operator.
// Since C++11 we also define move operations
X::X(X&& rhs) {}; // Move Constructor
X& operator=(X&& rhs)
{return *this;} // Move Assignment
Note:
The default constructor is not built if ANY constructor is defined.
The other methods are not built if the user defines an alternative.
What is slightly more interesting is the default implementation when we have members and a base:
class Y: public X
{
int a; // POD data
int* b; // POD (that also happens to be a pointer)
Z z; // A class
};
// Note: There are two variants of the default constructor.
// Both are used depending on context when the compiler defined version
// of the default constructor is used.
//
// One does `default initialization`
// One does `zero initialization`
// Objects are zero initialized when
// They are 'static storage duration'
// **OR** You use the braces when using the default constructor
Y::Y() // Zero initializer
: X() // Zero initializer
, a(0)
, b(0)
, z() // Zero initializer of Z called.
{}
// Objects are default initialized when
// They are 'automatic storage duration'
// **AND** don't use the braces when using the default constructor
Y::Y()
:X // Not legal syntax trying to portray default initialization of X (base class)
//,a // POD: uninitialized.
//,b // POD: uninitialized.
,z // Not legal syntax trying to portray default initialization of z (member)
{}
//
// Note: It is actually hard to correctly zero initialize a 'automatic storage duration'
// variable (because of the parsing problems it tends to end up a a function
// declaration). Thus in a function context member variables can have indeterminate
// values because of default initialization. Thus it is always good practice to
// to initialize all members of your class during construction (preferably in the
// initialization list).
//
// Note: This was defined this way so that the C++ is backward compatible with C.
// And obeys the rule of don't do more than you need too (because we want the C++
// code to be as fast and efficient as possible.
Y::Y(Y const& rhs)
:X(rhs) // Copy construct the base
,a(rhs.a) // Copy construct each member using the copy constructor.
,b(rhs.b) // NOTE: The order is explicitly defined
,z(rhs.z) // as the order of declaration in the class.
{}
Y& operator=(Y const& rhs)
{
X::operator=(rhs); // Use base copy assignment operator
a = rhs.a; // Use the copy assignment operator on each member.
b = rhs.b; // NOTE: The order is explicitly defined
z = rhs.z; // as the order of declaration in the class.
return(*this);
}
Y::~Y()
{
Your Code first
}
// Not legal code. Trying to show what happens.
: ~z()
, ~b() // Does nothing for pointers.
, ~a() // Does nothing for POD types
, ~X() ; // Base class destructed last.
// Move semantics:
Y::Y(Y&& rhs)
:X(std::move(rhs)) // Move construct the base
,a(std::move(rhs.a)) // Move construct each member using the copy constructor.
,b(std::move(rhs.b)) // NOTE: The order is explicitly defined
,z(std::move(rhs.z)) // as the order of declaration in the class.
{}
Y& operator=(Y&& rhs)
{
X::operator=(std::move(rhs)); // Use base move assignment operator
a = std::move(rhs.a); // Use the move assignment operator on each member.
b = std::move(rhs.b); // NOTE: The order is explicitly defined
z = std::move(rhs.z); // as the order of declaration in the class.
return(*this);
}
Just to expand on Armen Tsirunyan answer here are the signatures for the methods:
// C++03
MyClass(); // Default constructor
MyClass(const MyClass& other); // Copy constructor
MyClass& operator=(const MyClass& other); // Copy assignment operator
~MyClass(); // Destructor
// C++11 adds two more
MyClass(MyClass&& other) noexcept; // Move constructor
MyClass& operator=(MyClass&& other) noexcept; // Move assignment operator
Default methods assigned by compiler for a empty class:
http://cplusplusinterviews.blogspot.sg/2015/04/compiler-default-methods.html
Is that it?
Yes thats it.
Compiler generates by default
- A default constructor
- A copy constructor
- A copy assignment operator
- A destructor
for a class
You can see the default constructor, the copy constructor and the assignment operator being generated by default when you use -ast-dump
option of Clang
prasoon@prasoon-desktop ~ $ cat empty.cpp && clang++ -cc1 -ast-dump empty.cpp
class empty
{};
int main()
{
empty e;
empty e2 = e;
{
empty e3;
e3 = e;
}
}
typedef char *__builtin_va_list;
class empty {
class empty;
inline empty() throw(); //default c-tor
//copy c-tor
inline empty(empty const &) throw() (CompoundStmt 0xa0b1050 <empty.cpp:1:7>)
//assignment operator
inline empty &operator=(empty const &) throw() (CompoundStmt 0xa0b1590 <empty.cpp:1:7>
(ReturnStmt 0xa0b1578 <col:7>
(UnaryOperator 0xa0b1558 <col:7> 'class empty' prefix '*'
(CXXThisExpr 0xa0b1538 <col:7> 'class empty *' this))))
};
精彩评论