Copy-constructors are a special type of constructor which are implicitly defined by the compiler if the programmer does not explicitly declare one. First, consider this code:
1 2 3 4
|
class SimpleClass
{
int Data_;
};
|
Nothing to it, right? Well, the compiler will implicitly declare and define a copy-constructor which will look like this:
1 2 3 4 5 6 7 8 9 10 11 12 13
|
class SimpleClass
{
public:
SimpleClass( SimpleClass const &Instance_ )
: Data_( Instance_.Data_ )
{ }
};
int main( )
{
SimpleClass SC_;
// Do something with SC_...
}
|
Constructors and destructors implicitly declared by the compiler are non-virtual, in-lined and the constructors perform member-wise copying on each data-member. A constructor will only be defined if it's use is warranted. The parameter, "
Instance_", of the copy-constructor is a reference to an instance of another "
SimpleClass" instance -- the parameter is declared as constant so that temporary instances of "
SimpleClass" can be bound to it.
The copy-assignment operator works the same way as the copy-constructor. Just like the constructors and destructor, the copy-assignment operator is also implicitly declared and defined by the compiler. Unlike the copy-constructor, however, the copy-assignment operator will return a reference to itself unless the programmer defines their own copy-assignment operator with a different return-type.
The "
this" pointer is a parameter that's implicitly added to the parameter list of each function that's associated with a class. Static functions of a class don't count because they're not associated with a class. In non-constant member-functions, "
this" is defined like so:
1 2 3 4 5 6
|
// [Note: "this" is defined by the compiler, so the following code is illegal -- end note]
class SimpleClass
{
public:
void MemberFunction( SimpleClass * const this, /* ...other params... */ );
};
|
As you can see, "
this" is declared as a constant pointer to a non-constant "
SimpleClass" instance. The reason why it's a constant pointer is because "
this" cannot point to any other instance until the function call ends. Therefore, any attempt to redirect "
this" will result in a compiler error.
In constant member-functions, the declaration of "
this" is modified to respect the const qualifier, like so:
1 2 3 4 5
|
class SimpleClass
{
public:
void MemberFunction( SimpleClass const * const this, /* ...other params... */ ) const;
};
|
As you can see, the declaration of "
this" is now a constant pointer to a constant "
SimpleClass" instance. Consequently, any attempt to modify the instance pointed-to by "
this" will result in an error unless the data-member you're trying to modify is "
mutable". For example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
|
class SimpleClass
{
public:
void ModifyA( ) const
{
DataA_ = 10; // Error: "this" is constant.
}
void ModifyB( ) const
{
DataB_ = 10; // OK
}
private:
int DataA_;
mutable int DataB_;
};
|
"
mutable" data-members are allowed to change their state through constant member-functions -- this is the reason why "
mutable" exists. If a data-member of a class instance must change, regardless of whether the instance is constant, a "
mutable" data-member can change since "
mutable" data-members are not subject to const-checking; hence the latter.
See here for more: http://www.cplusplus.com/doc/tutorial/classes/
Wazzak