cppannotations/annotations/yo/memory/default.yo

125 lines
4.6 KiB
Text
Raw Normal View History

As we've seen, classes by default offer a copy constructor and assignment
operator. These class members are implemented so as to provide basic support:
data members of primitive data types are copied byte-by-byte, but for class
2016-11-09 09:11:41 +01:00
type data members their corresponding copy constructors c.q. assignment
2017-05-22 22:56:36 +02:00
operators are called. The compiler also attempts to provide default
implementations for move constructors and move assignment operators. However,
the default constructors and assignment operators cannot always be provided.
These are the rules the compiler applies when deciding what to provide or not
to provide:
itemization(
it() If the copy constructor or the copy assignment operator is declared,
then the default move constructor and move assignment operator are suppressed;
their use is replaced by the corresponding copy operation (constructor or
assignment operator);
it() If the move constructor or the move assignment operator is declared
then the copy constructor and the copy assignment operator are implicitly
declared as deleted, and can therefore not be used anymore;
it() If em(either) the move constructor em(or) the move assignment
operator is declared, then (in addition to suppressing the copy operations)
the default implementation of the other move-member is also suppressed;
it() In all other cases the default copy and move constructors em(and) the
default copy and assignment operators are provided.
)
If default implementations of copy or move constructors or assignment
operators are suppressed, but they should be available, then it's easy to
provide the default implementations by specifying the required signatures, to
which the specification `tt(= default)' is added.
Here is an example of a class offering all defaults: constructor, copy
2017-05-22 22:56:36 +02:00
constructor, move constructor, copy assignment operator and move assignment
operator:
verb(
class Defaults
{
int d_x;
Mov d_mov;
};
)
2017-05-22 22:56:36 +02:00
Assuming that tt(Mov) is a class offering move operations in addition
2017-05-22 22:56:36 +02:00
to the standard copy operations, then the following actions are performed
on the destination's tt(d_mov) and tt(d_x):
verb(
Defaults factory();
int main()
{ Mov operation: d_x:
---------------------------
Defaults one; Mov(), undefined
Defaults two(one); Mov(Mov const &), one.d_x
2012-02-26 17:19:16 +01:00
Defaults three(factory()); Mov(Mov &&tmp), tmp.d_x
one = two; Mov::operator=( two.d_x
Mov const &),
2012-02-26 17:19:16 +01:00
one = factory(); Mov::operator=( tmp.d_x
Mov &&tmp)
}
)
2017-05-22 22:56:36 +02:00
If, tt(Defaults) declares at least one constructor (not being the copy- or
move constructor) as well as the copy assignment operators then only the
default copy- and declared assignment operator are available. E.g.:
verb(
class Defaults
{
int d_x;
Mov d_mov;
public:
Defaults(int x);
2017-05-22 22:56:36 +02:00
Default &operator=(Default const &rhs);
};
Defaults factory();
int main()
{ Mov operation: resulting d_x:
--------------------------------
Defaults one; ERROR: not available
2017-05-22 22:56:36 +02:00
Defaults two(one); Mov(Mov const &), one.d_x
Defaults three(factory()); Mov(Mov const &), one.d_x
2012-02-26 17:19:16 +01:00
2017-05-22 22:56:36 +02:00
one = two; Mov::operatpr=( two.d_x
Mov const &)
one = factory(); Mov::operator=( tmp.d_x
Mov const &)
}
)
To reestablish the defaults, append tt(= default) to the appropriate
declarations:
verb(
class Defaults
{
int d_x;
Mov d_mov;
public:
Defaults() = default;
Defaults(int x);
2017-05-22 22:56:36 +02:00
// Default(Default const &) remains available (by default)
Defaults(Defaults &&tmp) = default;
2017-05-22 22:56:36 +02:00
Defaults operator=(Defaults const &rhs);
Defaults operator=(Defaults &&tmp) = default;
};
2012-02-26 17:19:16 +01:00
)
Be cautious, declaring defaults, as default implementations copy data members
of primitive types byte-by-byte from the source object to the destination
object. This is likely to cause problems with pointer type data members.
The ti(= default) suffix can only be used when declaring constructors or
assignment operators in the class's public section.
2017-05-22 22:56:36 +02:00