@@ -20271,24 +20271,28 @@ and errors (when we didn't deal correctly with semi-constructed objects consiste
20271
20271
20272
20272
##### Example, bad
20273
20273
20274
+ // Old conventional style: many problems
20275
+
20274
20276
class Picture
20275
20277
{
20276
20278
int mx;
20277
20279
int my;
20278
20280
char * data;
20279
20281
public:
20282
+ // main problem: constructor does not fully construct
20280
20283
Picture(int x, int y)
20281
20284
{
20282
- mx = x,
20285
+ mx = x; // also bad: assignment in constructor body rather than in member initializer
20283
20286
my = y;
20284
- data = nullptr;
20287
+ data = nullptr; // also bad: constant initialization in constructor rather than in member initializer
20285
20288
}
20286
20289
20287
20290
~Picture()
20288
20291
{
20289
20292
Cleanup();
20290
20293
}
20291
20294
20295
+ // bad: two-phase initialization
20292
20296
bool Init()
20293
20297
{
20294
20298
// invariant checks
@@ -20298,10 +20302,11 @@ and errors (when we didn't deal correctly with semi-constructed objects consiste
20298
20302
if (data) {
20299
20303
return false;
20300
20304
}
20301
- data = (char*) malloc(mx*my*sizeof(int));
20305
+ data = (char*) malloc(mx*my*sizeof(int)); // also bad: owning raw * and malloc
20302
20306
return data != nullptr;
20303
20307
}
20304
20308
20309
+ // also bad: no reason to make cleanup a separate function
20305
20310
void Cleanup()
20306
20311
{
20307
20312
if (data) free(data);
@@ -20320,11 +20325,11 @@ and errors (when we didn't deal correctly with semi-constructed objects consiste
20320
20325
20321
20326
class Picture
20322
20327
{
20323
- ptrdiff_t mx;
20324
- ptrdiff_t my;
20328
+ int mx;
20329
+ int my;
20325
20330
vector<char> data;
20326
20331
20327
- static ptrdiff_t check_size(ptrdiff_t size)
20332
+ static int check_size(int size)
20328
20333
{
20329
20334
// invariant check
20330
20335
Expects(size > 0);
@@ -20333,14 +20338,15 @@ and errors (when we didn't deal correctly with semi-constructed objects consiste
20333
20338
20334
20339
public:
20335
20340
// 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)
20337
20342
: mx(check_size(x))
20338
20343
, my(check_size(y))
20339
20344
// now we know x and y have a valid size
20340
20345
, data(mx * my * sizeof(int)) // will throw std::bad_alloc on error
20341
20346
{
20342
20347
// picture is ready-to-use
20343
20348
}
20349
+
20344
20350
// compiler generated dtor does the job. (also see C.21)
20345
20351
};
20346
20352
0 commit comments