mirror of
https://github.com/isocpp/CppCoreGuidelines.git
synced 2025-12-17 20:54:41 +03:00
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:
committed by
Herb Sutter
parent
0f57785d2b
commit
385199cc90
@@ -20030,9 +20030,88 @@ Following this rule leads to weaker invariants,
|
|||||||
more complicated code (having to deal with semi-constructed objects),
|
more complicated code (having to deal with semi-constructed objects),
|
||||||
and errors (when we didn't deal correctly with semi-constructed objects consistently).
|
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
|
##### Alternative
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user