mirror of
https://github.com/isocpp/CppCoreGuidelines.git
synced 2024-03-22 13:30:58 +08:00
commit
2ab0ecbfeb
|
@ -3271,7 +3271,7 @@ Also, copying may lead to slicing.
|
||||||
// ...
|
// ...
|
||||||
};
|
};
|
||||||
|
|
||||||
The problem of whether `Handle` is responsible for the destruction of its `Shape` is the same as for <a ref="#Rc-dtor-ptr">the pointer case</a>:
|
The problem of whether `Handle` is responsible for the destruction of its `Shape` is the same as for [the pointer case](#Rc-dtor-ptr):
|
||||||
If the `Handle` owns the object referred to by `s` it must have a destructor.
|
If the `Handle` owns the object referred to by `s` it must have a destructor.
|
||||||
|
|
||||||
**Example**:
|
**Example**:
|
||||||
|
@ -5505,7 +5505,7 @@ Here, we ignore such cases.
|
||||||
* [R.14: ??? array vs. pointer parameter](#Rr-ap)
|
* [R.14: ??? array vs. pointer parameter](#Rr-ap)
|
||||||
* [R.15: Always overload matched allocation/deallocation pairs](#Rr-pair)
|
* [R.15: Always overload matched allocation/deallocation pairs](#Rr-pair)
|
||||||
|
|
||||||
* <a name ="Rr-summary-smartptrs"></a>Smart pointer rule summary:
|
* <a name ="Rr-summary-smartptrs"></a> Smart pointer rule summary:
|
||||||
* [R.20: Use `unique_ptr` or `shared_ptr` to represent ownership](#Rr-owner)
|
* [R.20: Use `unique_ptr` or `shared_ptr` to represent ownership](#Rr-owner)
|
||||||
* [R.21: Prefer `unique_ptr` over `shared_ptr` unless you need to share ownership](#Rr-unique)
|
* [R.21: Prefer `unique_ptr` over `shared_ptr` unless you need to share ownership](#Rr-unique)
|
||||||
* [R.22: Use `make_shared()` to make `shared_ptr`s](#Rr-make_shared)
|
* [R.22: Use `make_shared()` to make `shared_ptr`s](#Rr-make_shared)
|
||||||
|
@ -8116,7 +8116,7 @@ Lock-free programming rule summary:
|
||||||
* ???
|
* ???
|
||||||
* ???
|
* ???
|
||||||
|
|
||||||
### <a name="Rconc"></a>Don't use lock-free programming unless you absolutely have to
|
### <a name="Rconc"></a> Don't use lock-free programming unless you absolutely have to
|
||||||
|
|
||||||
**Reason**: It's error-prone and requires expert level knowledge of language features, machine architecture, and data structures.
|
**Reason**: It's error-prone and requires expert level knowledge of language features, machine architecture, and data structures.
|
||||||
|
|
||||||
|
@ -11821,7 +11821,7 @@ Modernization can be much faster, simpler, and safer when supported with analysi
|
||||||
This section contains follow-up material on rules and sets of rules.
|
This section contains follow-up material on rules and sets of rules.
|
||||||
In particular, here we present further rationale, longer examples, and discussions of alternatives.
|
In particular, here we present further rationale, longer examples, and discussions of alternatives.
|
||||||
|
|
||||||
### <a name="Sd-order"></a>Discussion: Define and initialize member variables in the order of member declaration
|
### <a name="Sd-order"></a> Discussion: Define and initialize member variables in the order of member declaration
|
||||||
|
|
||||||
Member variables are always initialized in the order they are declared in the class definition, so write them in that order in the constructor initialization list. Writing them in a different order just makes the code confusing because it won't run in the order you see, and that can make it hard to see order-dependent bugs.
|
Member variables are always initialized in the order they are declared in the class definition, so write them in that order in the constructor initialization list. Writing them in a different order just makes the code confusing because it won't run in the order you see, and that can make it hard to see order-dependent bugs.
|
||||||
|
|
||||||
|
@ -11847,11 +11847,11 @@ If the class definition and the constructor body are in separate files, the long
|
||||||
|
|
||||||
[[Cline99]](#Cline99) §22.03-11, [[Dewhurst03]](Dewhurst03) §52-53, [[Koenig97]](#Koenig97) §4, [[Lakos96]](#Lakos96) §10.3.5, [[Meyers97]](#Meyers97) §13, [[Murray93]](#Murray93) §2.1.3, [[Sutter00]](#Sutter00) §47
|
[[Cline99]](#Cline99) §22.03-11, [[Dewhurst03]](Dewhurst03) §52-53, [[Koenig97]](#Koenig97) §4, [[Lakos96]](#Lakos96) §10.3.5, [[Meyers97]](#Meyers97) §13, [[Murray93]](#Murray93) §2.1.3, [[Sutter00]](#Sutter00) §47
|
||||||
|
|
||||||
### <a name="???">Use of `=`, `{}`, and `()` as initializers</a>
|
### <a name="???"></a> Use of `=`, `{}`, and `()` as initializers
|
||||||
|
|
||||||
???
|
???
|
||||||
|
|
||||||
### <a name="Sd-factory"></a>Discussion: Use a factory function if you need "virtual behavior" during initialization
|
### <a name="Sd-factory"></a> Discussion: Use a factory function if you need "virtual behavior" during initialization
|
||||||
|
|
||||||
If your design wants virtual dispatch into a derived class from a base class constructor or destructor for functions like `f` and `g`, you need other techniques, such as a post-constructor -- a separate member function the caller must invoke to complete initialization, which can safely call `f` and `g` because in member functions virtual calls behave normally. Some techniques for this are shown in the References. Here's a non-exhaustive list of options:
|
If your design wants virtual dispatch into a derived class from a base class constructor or destructor for functions like `f` and `g`, you need other techniques, such as a post-constructor -- a separate member function the caller must invoke to complete initialization, which can safely call `f` and `g` because in member functions virtual calls behave normally. Some techniques for this are shown in the References. Here's a non-exhaustive list of options:
|
||||||
|
|
||||||
|
@ -11906,7 +11906,7 @@ In summary, no post-construction technique is perfect. The worst techniques dodg
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <a name="Sd-dtor"></a>Discussion: Make base class destructors public and virtual, or protected and nonvirtual
|
### <a name="Sd-dtor"></a> Discussion: Make base class destructors public and virtual, or protected and nonvirtual
|
||||||
|
|
||||||
Should destruction behave virtually? That is, should destruction through a pointer to a `base` class should be allowed? If yes, then `base`'s destructor must be public in order to be callable, and virtual otherwise calling it results in undefined behavior. Otherwise, it should be protected so that only derived classes can invoke it in their own destructors, and nonvirtual since it doesn't need to behave virtually virtual.
|
Should destruction behave virtually? That is, should destruction through a pointer to a `base` class should be allowed? If yes, then `base`'s destructor must be public in order to be callable, and virtual otherwise calling it results in undefined behavior. Otherwise, it should be protected so that only derived classes can invoke it in their own destructors, and nonvirtual since it doesn't need to behave virtually virtual.
|
||||||
|
|
||||||
|
@ -12078,7 +12078,7 @@ When using exceptions as your error handling mechanism, always document this beh
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## <a name ="Sd-consistent"></a>Define Copy, move, and destroy consistently
|
## <a name ="Sd-consistent"></a> Define Copy, move, and destroy consistently
|
||||||
|
|
||||||
**Reason**: ???
|
**Reason**: ???
|
||||||
|
|
||||||
|
@ -12176,7 +12176,7 @@ Resource management rule summary:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <a name="Cr-safety"></a>Provide strong resource safety; that is, never leak anything that you think of as a resource
|
### <a name="Cr-safety"></a> Provide strong resource safety; that is, never leak anything that you think of as a resource
|
||||||
|
|
||||||
**Reason**: Prevent leaks. Leaks can lead to performance degradation, mysterious error, system crashes, and security violations.
|
**Reason**: Prevent leaks. Leaks can lead to performance degradation, mysterious error, system crashes, and security violations.
|
||||||
|
|
||||||
|
@ -12192,7 +12192,7 @@ Resource management rule summary:
|
||||||
int sz;
|
int sz;
|
||||||
};
|
};
|
||||||
|
|
||||||
This class is a resource handle. It manages the lifetime of the `T`s. To do so, `Vector` must define or delete <a ref="???">the set of special operations</a> (constructors, a destructor, etc.).
|
This class is a resource handle. It manages the lifetime of the `T`s. To do so, `Vector` must define or delete [the set of special operations](???) (constructors, a destructor, etc.).
|
||||||
|
|
||||||
**Example**:
|
**Example**:
|
||||||
|
|
||||||
|
@ -12201,7 +12201,7 @@ This class is a resource handle. It manages the lifetime of the `T`s. To do so,
|
||||||
**Enforcement**: The basic technique for preventing leaks is to have every resource owned by a resource handle with a suitable destructor. A checker can find "naked `new`s". Given a list of C-style allocation functions (e.g., `fopen()`), a checker can also find uses that are not managed by a resource handle. In general, "naked pointers" can be viewed with suspicion, flagged, and/or analyzed. A a complete list of resources cannot be generated without human input (the definition of "a resource" is necessarily too general), but a tool can be "parameterized" with a resource list.
|
**Enforcement**: The basic technique for preventing leaks is to have every resource owned by a resource handle with a suitable destructor. A checker can find "naked `new`s". Given a list of C-style allocation functions (e.g., `fopen()`), a checker can also find uses that are not managed by a resource handle. In general, "naked pointers" can be viewed with suspicion, flagged, and/or analyzed. A a complete list of resources cannot be generated without human input (the definition of "a resource" is necessarily too general), but a tool can be "parameterized" with a resource list.
|
||||||
|
|
||||||
|
|
||||||
### <a name="Cr-never"></a>Never throw while holding a resource not owned by a handle
|
### <a name="Cr-never"></a> Never throw while holding a resource not owned by a handle
|
||||||
|
|
||||||
**Reason**: That would be a leak.
|
**Reason**: That would be a leak.
|
||||||
|
|
||||||
|
@ -12235,14 +12235,14 @@ For starters, we know about the standard-library containers, `string`, and smart
|
||||||
The use of `array_view` and `string_view` should help a lot (they are not resource handles).
|
The use of `array_view` and `string_view` should help a lot (they are not resource handles).
|
||||||
|
|
||||||
|
|
||||||
### <a name="Cr-raw"></a>A "raw" pointer or reference is never a resource handle
|
### <a name="Cr-raw"></a> A "raw" pointer or reference is never a resource handle
|
||||||
|
|
||||||
**Reason** To be able to distinguish owners from views.
|
**Reason** To be able to distinguish owners from views.
|
||||||
|
|
||||||
**Note**: This is independent of how you "spell" pointer: `T*`, `T&`, `Ptr<T>` and `Range<T>` are not owners.
|
**Note**: This is independent of how you "spell" pointer: `T*`, `T&`, `Ptr<T>` and `Range<T>` are not owners.
|
||||||
|
|
||||||
|
|
||||||
### <a name="Cr-outlive"></a>Never let a pointer outlive the object it points to
|
### <a name="Cr-outlive"></a> Never let a pointer outlive the object it points to
|
||||||
|
|
||||||
**Reason**: To avoid extremely hard-to-find errors. Dereferencing such a pointer is undefined behavior and could lead to violations of the type system.
|
**Reason**: To avoid extremely hard-to-find errors. Dereferencing such a pointer is undefined behavior and could lead to violations of the type system.
|
||||||
|
|
||||||
|
@ -12267,7 +12267,7 @@ The `string`s of `v` are destroyed upon exit from `bad()` and so is `v` itself.
|
||||||
**Enforcement**: Most compilers already warn about simple cases and has the information to do more. Consider any pointer returned from a function suspect. Use containers, resource handles, and views (e.g., `array_view` known not to be resource handles) to lower the number of cases to be examined. For starters, consider every class with a destructor a resource handle.
|
**Enforcement**: Most compilers already warn about simple cases and has the information to do more. Consider any pointer returned from a function suspect. Use containers, resource handles, and views (e.g., `array_view` known not to be resource handles) to lower the number of cases to be examined. For starters, consider every class with a destructor a resource handle.
|
||||||
|
|
||||||
|
|
||||||
### <a name="Cr-templates"></a>Use templates to express containers (and other resource handles)
|
### <a name="Cr-templates"></a> Use templates to express containers (and other resource handles)
|
||||||
|
|
||||||
**Reason**: To provide statically type-safe manipulation of elements.
|
**Reason**: To provide statically type-safe manipulation of elements.
|
||||||
|
|
||||||
|
@ -12279,7 +12279,7 @@ The `string`s of `v` are destroyed upon exit from `bad()` and so is `v` itself.
|
||||||
int sz;
|
int sz;
|
||||||
};
|
};
|
||||||
|
|
||||||
### <a name="Cr-value-return"></a>Return containers by value (relying on move for efficiency)
|
### <a name="Cr-value-return"></a> Return containers by value (relying on move for efficiency)
|
||||||
|
|
||||||
**Reason**: To simplify code and eliminate a need for explicit memory management. To bring an object into a surrounding scope, thereby extending its lifetime.
|
**Reason**: To simplify code and eliminate a need for explicit memory management. To bring an object into a surrounding scope, thereby extending its lifetime.
|
||||||
|
|
||||||
|
@ -12294,7 +12294,7 @@ The `string`s of `v` are destroyed upon exit from `bad()` and so is `v` itself.
|
||||||
**Enforcement**: Check for pointers and references returned from functions and see if they are assigned to resource handles (e.g., to a `unique_ptr`).
|
**Enforcement**: Check for pointers and references returned from functions and see if they are assigned to resource handles (e.g., to a `unique_ptr`).
|
||||||
|
|
||||||
|
|
||||||
### <a name="Cr-handle"></a>If a class is a resource handle, it needs a constructor, a destructor, and copy and/or move operations
|
### <a name="Cr-handle"></a> If a class is a resource handle, it needs a constructor, a destructor, and copy and/or move operations
|
||||||
|
|
||||||
**Reason**: To provide complete control of the lifetime of the resource. To provide a coherent set of operations on the resource.
|
**Reason**: To provide complete control of the lifetime of the resource. To provide a coherent set of operations on the resource.
|
||||||
|
|
||||||
|
@ -12314,7 +12314,7 @@ Now `Named` has a default constructor, a destructor, and efficient copy and move
|
||||||
**Enforcement**: In general, a tool cannot know if a class is a resource handle. However, if a class has some of [the default operations](???), it should have all, and if a class has a member that is a resource handle, it should be considered a resource handle.
|
**Enforcement**: In general, a tool cannot know if a class is a resource handle. However, if a class has some of [the default operations](???), it should have all, and if a class has a member that is a resource handle, it should be considered a resource handle.
|
||||||
|
|
||||||
|
|
||||||
### <a name="Cr-list"></a>If a class is a container, give it an initializer-list constructor
|
### <a name="Cr-list"></a> If a class is a container, give it an initializer-list constructor
|
||||||
|
|
||||||
**Reason**: It is common to need an initial set of elements.
|
**Reason**: It is common to need an initial set of elements.
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user