Added bad and good example to NR.5 in CppCoreGuidelines.md (#1401)

* Added bad and goof example to NR.5 in CppCoreGuidelines.md

Added bad and good example to NR.5 Don’t: Don’t do substantive work in a constructor; instead use two-phase initialization.
I think it could be suitable.

* adjusted coding style

* removed extra space

* removed one more whitespace

* removed spaces before note to make it a blank line

* made Cleanup method from bad example return void

* some changes after review comments

- removed try catch
- removed defaulted dtor
- changed int to size_t, removed check for even.
- Expects() for invariant check
- typo

* spell check adjustment

* moved comment up for met the line length

* changed variablename in good example

... they were named same after removed the try catch scope

* changed afer comments

- changed check_size() function to a static member function 
- fixed comment mentioning the default contract violation behavior.
This commit is contained in:
Florian Thake 2019-04-25 20:21:50 +02:00 committed by Herb Sutter
parent 0f57785d2b
commit 385199cc90

View File

@ -20030,9 +20030,88 @@ Following this rule leads to weaker invariants,
more complicated code (having to deal with semi-constructed objects),
and errors (when we didn't deal correctly with semi-constructed objects consistently).
##### Example
##### Example, bad
???
class Picture
{
int mx;
int my;
char * data;
public:
Picture(int x, int y)
{
mx = x,
my = y;
data = nullptr;
}
~Picture()
{
Cleanup();
}
bool Init()
{
// invariant checks
if (mx <= 0 || my <= 0) {
return false;
}
if (data) {
return false;
}
data = (char*) malloc(x*y*sizeof(int));
return data != nullptr;
}
void Cleanup()
{
if (data) free(data);
data = nullptr;
}
};
Picture picture(100, 0); // not ready-to-use picture here
// this will fail..
if (!picture.Init()) {
puts("Error, invalid picture");
}
// now have a invalid picture object instance.
##### Example, good
class Picture
{
size_t mx;
size_t my;
vector<char> data;
static size_t check_size(size_t s)
{
// invariant check
Expects(s > 0);
return s;
}
public:
// even more better would be a class for a 2D Size as one single parameter
Picture(size_t x, size_t y)
: mx(check_size(x))
, my(check_size(y))
// now we know x and y have a valid size
, data(mx * my * sizeof(int)) // will throw std::bad_alloc on error
{
// picture is ready-to-use
}
// compiler generated dtor does the job. (also see C.21)
};
Picture picture1(100, 100);
// picture is ready-to-use here...
// not a valid size for y,
// default contract violation behavior will call std::terminate then
Picture picture2(100, 0);
// not reach here...
##### Alternative