C ++ core principles C.43: guaranteed (type value) may have a default constructor class copy

C.43: Ensure that a copyable (value type) class has a default constructor

C.43: ensuring (type value) may have a default constructor class copy

 

 

Reason (reason)

Many language and library facilities rely  on default constructors to initialize their elements, e.g. T a[10] and std::vector<T> v(10). A default constructor often simplifies the task of defining a suitable moved-from state for a type that is also copyable.

Many languages ​​and libraries facilities rely on default constructor initializes their elements, for example T a [0] and std :: vector <T> v (10). Default constructor may often be simplified to copy the appropriate class definition work out state.

 

 

Note (Note)

A value type is a class that is copyable (and usually also comparable). It is closely related to the notion of Regular type from EoP and the Palo Alto TR.

Can be copied (usually comparable) class called value type. The link between it and the regular type of "original programming", "STL conceptual design" is mentioned very closely.

 

Regular type:

https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#SS-concrete

Original programming:

http://elementsofprogramming.com/

STL conceptual design:

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3351.pdf

 

 

 

Example (Example)

class Date { // BAD: no default constructor
public:
    Date(int dd, int mm, int yyyy);
    // ...
};

vector<Date> vd1(1000);   // default Date needed here
vector<Date> vd2(1000, Date{Month::October, 7, 1885});   // alternative

The default constructor is only auto-generated if there is no user-declared constructor, hence it's impossible to initialize the vectorvd1in the example above. The absence of a default value can cause surprises for users and complicate its use, so if one can be reasonably defined, it should be.、

Default constructor does not exist only in the definition of the user to be automatically generated constructor, so as the above code as the initialization vector vd1 is impossible. The default value of the missing may make users by surprise and increases the difficulty of use, so if it is possible to reasonably define it, to do that.

Date is chosen to encourage thought: There is no "natural" default date (the big bang is too far back in time to be useful for most people), so this example is non-trivial.{0, 0, 0} is not a valid date in most calendar systems, so choosing that would be introducing something like floating-point's NaN. However, most realistic Date classes have a "first date" (e.g. January 1, 1970 is popular), so making that the default is usually trivial.

Select the category to date THINKING: There is no "natural" default date (for most people, at the moment of the Big Bang as the default time needs to be rolled back too much, do not have practical significance), so this example does not have a general. {0,0,0} in most calendar systems are not legitimate date, so select it will cause problems similar floating-point NaN.

 

NaN: not a number, or an invalid number.

 

class Date {
public:
    Date(int dd, int mm, int yyyy);
    Date() = default; // [See also](#Rc-default)
    // ...
private:
    int dd = 1;
    int mm = 1;
    int yyyy = 1970;
    // ...
};

vector<Date> vd1(1000);

 

 

Note (Note)

A class with members that all have default constructors implicitly gets a default constructor:

If all members of a class has a default constructor, then this class is also implicitly get a default constructor.

struct X {
    string s;
    vector<int> v;
};

X x; // means X{{}, {}}; that is the empty string and the empty vector

Beware that built-in types are not properly default constructed:

Please note that the built-in types have not been properly default constructor:

struct X {
    string s;
    int i;
};

void f()
{
    X x;    // x.s is initialized to the empty string; x.i is uninitialized

    cout << x.s << ' ' << x.i << '\n';
    ++x.i;
}

Statically allocated objects of built-in types are by default initialized to 0, but local built-in variables are not. Beware that your compiler may default initialize local built-in variables, whereas an optimized build will not. Thus, code like the example above may appear to work, but it relies on undefined behavior. Assuming that you want initialization, an explicit default initialization can help:

Built-in types statically allocated initialized to 0 by default, but there is no local built-in types. Watch your compiler has built-in types may initialize local variables, but the compiler optimization state will not. Thus in the above example can be operation code looks, but it relies (compiler, translator's note) is not defined behavior. If you need to initialize and clear the default initialization can help:

struct X {
    string s;
    int i {};   // default initialize (to 0)
};

 

 

Notes (Note)

Classes that don't have a reasonable default construction are usually not copyable either, so they don't fall under this guideline.

Does not contain reasonable default constructor class action is not usually copy, so they is not a violation of this Code.

For example, a base class is not a value type (base classes should not be copyable) and so does not necessarily need a default constructor:

For example, the base class is not a value type (base class should not be copied) without the need default constructor.

// Shape is an abstract base class, not a copyable value type.
// It may or may not need a default constructor.
struct Shape {
    virtual void draw() = 0;
    virtual void rotate(int) = 0;
    // =delete copy/move functions
    // ...
};

A class that must acquire a caller-provided resource during construction often cannot have a default constructor, but it does not fall under this guideline because such a class is usually not copyable anyway:

If a class must ask the caller to provide resources during construction, generally you can not have a default constructor, but it does not violate this Code, because such classes are usually in any case can not be copied.

// std::lock_guard is not a copyable value type.
// It does not have a default constructor.
lock_guard g {mx};  // guard the mutex mx
lock_guard g2;      // error: guarding nothing

A class that has a "special state" that must be handled separately from other states by member functions or users causes extra work (and most likely more errors). Such a type can naturally use the special state as a default constructed value, whether or not it is copyable:

Some classes have some kind of "special status" and must be initiated by the user or member functions (most likely to be wrong more errors) special action apart from each other for processing. Of the type may naturally be used as the default configuration of the particular state of the initial value, whether it is copied.

// std::ofstream is not a copyable value type.
// It does happen to have a default constructor
// that goes along with a special "not open" state.
ofstream out {"Foobar"};
// ...
out << log(time, transaction);

Similar special-state types that are copyable, such as copyable smart pointers that have the special state "==nullptr", should use the special state as their default constructed value.

Similar types copy of a particular state, e.g. comprising such a special status "== nullptr" smart pointers can be copied, the state should be used as the special configuration of their initial default values.

However, it is preferable to have a default constructor default to a meaningful state such as std::strings "" and std::vectors {}.

However, a more desirable approach is to let the default constructor to generate a meaningful default state, e.g. std :: string of "" and std :: vectors {}.

 

 

Enforcement (Suggestions)

  • Flag classes that are copyable by = without a default constructor

    If the class implements the assignment operator but there is no default constructor prompt.

  • Flag classes that are comparable with == but not copyable

    If the class can be compared by the comparison operators but not copyable, prompt.

     

     

 

Description link

https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#c43-ensure-that-a-copyable-value-type-class-has-a-default-constructor

 


 

I think this article helpful? Welcome thumbs up and share it with more people.

Read more updated articles, please pay attention to micro-channel public number of object-oriented thinking []

Published 408 original articles · won praise 653 · views 290 000 +

Guess you like

Origin blog.csdn.net/craftsman1970/article/details/104447548