mirror of
https://github.com/isocpp/CppCoreGuidelines.git
synced 2024-03-22 13:30:58 +08:00
fix code blocks indented with tab (4 spaces instead)
This commit is contained in:
parent
8adf569a57
commit
777f7bc5fb
|
@ -3725,32 +3725,32 @@ How would a maintainer know whether `j` was deliberately uninitialized (probably
|
||||||
|
|
||||||
**Example*:
|
**Example*:
|
||||||
|
|
||||||
class B {
|
class B {
|
||||||
protected:
|
protected:
|
||||||
B() { /* ... */ } // create an imperfectly initialized object
|
B() { /* ... */ } // create an imperfectly initialized object
|
||||||
|
|
||||||
virtual void PostInitialize() // to be called right after construction
|
virtual void PostInitialize() // to be called right after construction
|
||||||
{
|
{
|
||||||
// ...
|
// ...
|
||||||
f(); // GOOD: virtual dispatch is safe
|
f(); // GOOD: virtual dispatch is safe
|
||||||
// ...
|
// ...
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual void f() = 0;
|
virtual void f() = 0;
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
static shared_ptr<T> Create() // interface for creating objects
|
static shared_ptr<T> Create() // interface for creating objects
|
||||||
{
|
{
|
||||||
auto p = make_shared<T>();
|
auto p = make_shared<T>();
|
||||||
p->PostInitialize();
|
p->PostInitialize();
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class D : public B { /* "¦ */ }; // some derived class
|
class D : public B { /* "¦ */ }; // some derived class
|
||||||
|
|
||||||
shared_ptr<D> p = D::Create<D>(); // creating a D object
|
shared_ptr<D> p = D::Create<D>(); // creating a D object
|
||||||
|
|
||||||
By making the constructor `protected` we avoid an incompletely constructed object escaping into the wild.
|
By making the constructor `protected` we avoid an incompletely constructed object escaping into the wild.
|
||||||
By providing the factory function `Create()`, we make construction (on the free store) convenient.
|
By providing the factory function `Create()`, we make construction (on the free store) convenient.
|
||||||
|
@ -6493,10 +6493,10 @@ However, beware that this may leave uninitialized data beyond the input - and th
|
||||||
|
|
||||||
The cost of initializing that array could be significant in some situations.
|
The cost of initializing that array could be significant in some situations.
|
||||||
However, such examples do tend to leave uninitialized variables accessible, so they should be treated with suspicion.
|
However, such examples do tend to leave uninitialized variables accessible, so they should be treated with suspicion.
|
||||||
|
|
||||||
constexpr int max = 8*1024;
|
constexpr int max = 8*1024;
|
||||||
int buf[max] = {0}; // better in some situations
|
int buf[max] = {0}; // better in some situations
|
||||||
f.read(buf, max);
|
f.read(buf, max);
|
||||||
|
|
||||||
When feasible use a library function that is know not to overflow. For example:
|
When feasible use a library function that is know not to overflow. For example:
|
||||||
|
|
||||||
|
@ -6796,13 +6796,13 @@ The definition of `a2` is C but not C++ and is considered a security risk
|
||||||
If at all possible, reduce the conditions to a simple set of alternatives (e.g., an `enum`) and don't mix up selection and initialization.
|
If at all possible, reduce the conditions to a simple set of alternatives (e.g., an `enum`) and don't mix up selection and initialization.
|
||||||
|
|
||||||
**Example**:
|
**Example**:
|
||||||
|
|
||||||
owner<istream&> in = [&]{
|
owner<istream&> in = [&]{
|
||||||
switch (source) {
|
switch (source) {
|
||||||
case default: owned=false; return cin;
|
case default: owned=false; return cin;
|
||||||
case command_line: owned=true; return *new istringstream{argv[2]};
|
case command_line: owned=true; return *new istringstream{argv[2]};
|
||||||
case file: owned=true; return *new ifstream{argv[2]};
|
case file: owned=true; return *new ifstream{argv[2]};
|
||||||
}();
|
}();
|
||||||
|
|
||||||
**Enforcement**: Hard. At best a heuristic. Look for an uninitialized variable followed by a loop assigning to it.
|
**Enforcement**: Hard. At best a heuristic. Look for an uninitialized variable followed by a loop assigning to it.
|
||||||
|
|
||||||
|
@ -11503,34 +11503,34 @@ If your design wants virtual dispatch into a derived class from a base class con
|
||||||
|
|
||||||
Here is an example of the last option:
|
Here is an example of the last option:
|
||||||
|
|
||||||
class B {
|
class B {
|
||||||
public:
|
public:
|
||||||
B() { /* ... */ f(); /*...*/ } // BAD: see Item 49.1
|
B() { /* ... */ f(); /*...*/ } // BAD: see Item 49.1
|
||||||
|
|
||||||
virtual void f() = 0;
|
virtual void f() = 0;
|
||||||
|
|
||||||
// ...
|
// ...
|
||||||
};
|
};
|
||||||
|
|
||||||
class B {
|
class B {
|
||||||
protected:
|
protected:
|
||||||
B() { /* ... */ }
|
B() { /* ... */ }
|
||||||
virtual void PostInitialize() // called right after construction
|
virtual void PostInitialize() // called right after construction
|
||||||
{ /* ... */ f(); /*...*/ } // GOOD: virtual dispatch is safe
|
{ /* ... */ f(); /*...*/ } // GOOD: virtual dispatch is safe
|
||||||
public:
|
public:
|
||||||
virtual void f() = 0;
|
virtual void f() = 0;
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
static shared_ptr<T> Create() { // interface for creating objects
|
static shared_ptr<T> Create() { // interface for creating objects
|
||||||
auto p = make_shared<T>();
|
auto p = make_shared<T>();
|
||||||
p->PostInitialize();
|
p->PostInitialize();
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class D : public B { /* "¦ */ }; // some derived class
|
class D : public B { /* "¦ */ }; // some derived class
|
||||||
|
|
||||||
shared_ptr<D> p = D::Create<D>(); // creating a D object
|
shared_ptr<D> p = D::Create<D>(); // creating a D object
|
||||||
|
|
||||||
This design requires the following discipline:
|
This design requires the following discipline:
|
||||||
|
|
||||||
|
@ -12000,20 +12000,18 @@ Alternatively, we will decide that no change is needed and delete the entry.
|
||||||
* What to do with leaks out of temporaries? : `p = (s1+s2).c_str();`
|
* What to do with leaks out of temporaries? : `p = (s1+s2).c_str();`
|
||||||
* pointer/iterator invalidation leading to dangling pointers
|
* pointer/iterator invalidation leading to dangling pointers
|
||||||
|
|
||||||
Example:
|
void bad()
|
||||||
|
{
|
||||||
|
int* p = new int[700];
|
||||||
|
int* q = &p[7];
|
||||||
|
delete p;
|
||||||
|
|
||||||
void bad()
|
vector<int> v(700);
|
||||||
{
|
int* q2 = &v[7];
|
||||||
int* p = new int[700];
|
v.resize(900);
|
||||||
int* q = &p[7];
|
|
||||||
delete p;
|
|
||||||
|
|
||||||
vector<int> v(700);
|
// ... use q and q2 ...
|
||||||
int* q2 = &v[7];
|
}
|
||||||
v.resize(900);
|
|
||||||
|
|
||||||
// ... use q and q2 ...
|
|
||||||
}
|
|
||||||
|
|
||||||
* LSP
|
* LSP
|
||||||
* private inheritance vs/and membership
|
* private inheritance vs/and membership
|
||||||
|
|
Loading…
Reference in New Issue
Block a user