@@ -20271,24 +20271,28 @@ and errors (when we didn't deal correctly with semi-constructed objects consiste
2027120271
2027220272##### Example, bad
2027320273
20274+ // Old conventional style: many problems
20275+
2027420276 class Picture
2027520277 {
2027620278 int mx;
2027720279 int my;
2027820280 char * data;
2027920281 public:
20282+ // main problem: constructor does not fully construct
2028020283 Picture(int x, int y)
2028120284 {
20282- mx = x,
20285+ mx = x; // also bad: assignment in constructor body rather than in member initializer
2028320286 my = y;
20284- data = nullptr;
20287+ data = nullptr; // also bad: constant initialization in constructor rather than in member initializer
2028520288 }
2028620289
2028720290 ~Picture()
2028820291 {
2028920292 Cleanup();
2029020293 }
2029120294
20295+ // bad: two-phase initialization
2029220296 bool Init()
2029320297 {
2029420298 // invariant checks
@@ -20298,10 +20302,11 @@ and errors (when we didn't deal correctly with semi-constructed objects consiste
2029820302 if (data) {
2029920303 return false;
2030020304 }
20301- data = (char*) malloc(mx*my*sizeof(int));
20305+ data = (char*) malloc(mx*my*sizeof(int)); // also bad: owning raw * and malloc
2030220306 return data != nullptr;
2030320307 }
2030420308
20309+ // also bad: no reason to make cleanup a separate function
2030520310 void Cleanup()
2030620311 {
2030720312 if (data) free(data);
@@ -20320,11 +20325,11 @@ and errors (when we didn't deal correctly with semi-constructed objects consiste
2032020325
2032120326 class Picture
2032220327 {
20323- ptrdiff_t mx;
20324- ptrdiff_t my;
20328+ int mx;
20329+ int my;
2032520330 vector<char> data;
2032620331
20327- static ptrdiff_t check_size(ptrdiff_t size)
20332+ static int check_size(int size)
2032820333 {
2032920334 // invariant check
2033020335 Expects(size > 0);
@@ -20333,14 +20338,15 @@ and errors (when we didn't deal correctly with semi-constructed objects consiste
2033320338
2033420339 public:
2033520340 // even better would be a class for a 2D Size as one single parameter
20336- Picture(ptrdiff_t x, ptrdiff_t y)
20341+ Picture(int x, int y)
2033720342 : mx(check_size(x))
2033820343 , my(check_size(y))
2033920344 // now we know x and y have a valid size
2034020345 , data(mx * my * sizeof(int)) // will throw std::bad_alloc on error
2034120346 {
2034220347 // picture is ready-to-use
2034320348 }
20349+
2034420350 // compiler generated dtor does the job. (also see C.21)
2034520351 };
2034620352
0 commit comments