construction, destruction, and assignmentweb.ntnu.edu.tw/~tcchiang/tpp2009/3_ctor, dtor, and...

30
The Practice of Programming, CSIE@NTNU, Fall, 2009 Construction, Destruction, and Assignment Instructor: Tsung-Che Chiang [email protected] Department of Computer Science and Information Engineering National Taiwan Normal University Ctor, Dtor, and Assignment,The Practice of Programming, CSIE@NTNU, 2009 Review of std::string

Upload: others

Post on 28-Jun-2020

3 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Construction, Destruction, and Assignmentweb.ntnu.edu.tw/~tcchiang/tpp2009/3_Ctor, dtor, and assignment.pdf · Construction, Destruction, and Assignment Instructor: Tsung-Che Chiang

The Practice of Programming, CSIE@NTNU, Fall, 2009

Construction, Destruction,and Assignment

Instructor: Tsung-Che [email protected]

Department of Computer Science and Information EngineeringNational Taiwan Normal University

“Ctor, Dtor, and Assignment,”The Practice of Programming, CSIE@NTNU, 2009

Review of std::string

Page 2: Construction, Destruction, and Assignmentweb.ntnu.edu.tw/~tcchiang/tpp2009/3_Ctor, dtor, and assignment.pdf · Construction, Destruction, and Assignment Instructor: Tsung-Che Chiang

“Ctor, Dtor, and Assignment,”The Practice of Programming, CSIE@NTNU, 2009

Review of std::string

“Ctor, Dtor, and Assignment,”The Practice of Programming, CSIE@NTNU, 20094

Warm-up Exercise

Define a class CPet Data members: name_, level_; Default values of name_ and level_ are “lucky”and 1,

respectively. Users can pass name and level when constructing a CPet

object.

Define a class CPlayer Data members: id_, name_, level_, pet_; id_ is a constant and must be provided when constructing aCPlayer object.

Default values of name_ and level_ are “player”and 1,respectively.

Users can pass player’s name, player’s level, pet’s name,and pet’s level when constructing a CPlayer object.

Page 3: Construction, Destruction, and Assignmentweb.ntnu.edu.tw/~tcchiang/tpp2009/3_Ctor, dtor, and assignment.pdf · Construction, Destruction, and Assignment Instructor: Tsung-Che Chiang

“Ctor, Dtor, and Assignment,”The Practice of Programming, CSIE@NTNU, 20095

Warm-up Exercise

“Ctor, Dtor, and Assignment,”The Practice of Programming, CSIE@NTNU, 20096

Warm-up Exercise

Page 4: Construction, Destruction, and Assignmentweb.ntnu.edu.tw/~tcchiang/tpp2009/3_Ctor, dtor, and assignment.pdf · Construction, Destruction, and Assignment Instructor: Tsung-Che Chiang

“Ctor, Dtor, and Assignment,”The Practice of Programming, CSIE@NTNU, 20097

Warm-up Exercise

1 [Player] (1) with pet [Lucky] (1)2 [Jay] (1) with pet [Lucky] (1)3 [NTNU] (100) with pet [Lucky] (1)4 [CSIE] (1) with pet [Piggy] (1)5 [tcchiang] (10) with pet [dragon] (100)

“Ctor, Dtor, and Assignment,”The Practice of Programming, CSIE@NTNU, 20098

Outline

Review of constructorsReview of destructorsRelated rules & guidelines

Page 5: Construction, Destruction, and Assignmentweb.ntnu.edu.tw/~tcchiang/tpp2009/3_Ctor, dtor, and assignment.pdf · Construction, Destruction, and Assignment Instructor: Tsung-Che Chiang

“Ctor, Dtor, and Assignment,”The Practice of Programming, CSIE@NTNU, 2009

Constructor

“Ctor, Dtor, and Assignment,”The Practice of Programming, CSIE@NTNU, 200910

Purpose of Constructors

If a class does not have a constructor, initializing itsobjects is a tedious task. (Remind: Always initialize variables.)

class CPlayer {public:

void SetMoney(int m) { money_ = m; }void SetNumLands(int l) { numLands_ = l; }// ...

private:int money_;int numLands_;// ...

};int main() {

CPlayer UncleATu;UncleATu.SetMoney(100000); // Tedious InitializationUncleATu.SetNumLands(0);// ...

}

Page 6: Construction, Destruction, and Assignmentweb.ntnu.edu.tw/~tcchiang/tpp2009/3_Ctor, dtor, and assignment.pdf · Construction, Destruction, and Assignment Instructor: Tsung-Che Chiang

“Ctor, Dtor, and Assignment,”The Practice of Programming, CSIE@NTNU, 200911

Purpose of Constructors

Even though you define a member function forinitialization, you may also forget to call it.

class CPlayer {public:

void Init() { money_ = 100000; numLands_ = 0; }// ...

private:int money_;int numLands_;// ...

};int main(){

CPlayer UncleATu;UncleATu.Init(); // What if we forget it?// ...

}

“Ctor, Dtor, and Assignment,”The Practice of Programming, CSIE@NTNU, 200912

Purpose of Constructors

The constructor is a simple and automatic way toinitialize the objects.class CPlayer {public:

CPlayer():money_(INIT_MONEY), numLands_(0) {}// ...

private:static const int INIT_MONEY = 100000;int money_;int numLands_;// ...

};int main(){

CPlayer UncleATu; // It is initialized automatically.// ...

}

Remember:Always Initialize Variables.

Page 7: Construction, Destruction, and Assignmentweb.ntnu.edu.tw/~tcchiang/tpp2009/3_Ctor, dtor, and assignment.pdf · Construction, Destruction, and Assignment Instructor: Tsung-Che Chiang

“Ctor, Dtor, and Assignment,”The Practice of Programming, CSIE@NTNU, 200913

Definition & Use of Constructors

We can define various constructors to satisfy ourneeds.

class CPlayer {public:

CPlayer() { ... } // default ctorCPlayer(const CPlayer &rhs) { ... } // copy ctorCPlayer(const std::string &name, bool isComp) { ... }// ...

};int main(){

CPlayer UncleATu;CPlayer LittleMei(“Mei”, false);CPlayer temp(LittleMei);CPlayer *ptrPlayer = new CPlayer(“PC1”, true);CPlayer arr[3] = {CPlayer(LittleMei),

CPlayer(“Mei, false)}// ...

}

Note.CPlayer UncleATu(); is a function declaration.

Note. arr[2] is initialized by the default ctor.

“Ctor, Dtor, and Assignment,”The Practice of Programming, CSIE@NTNU, 200914

Definition & Use of Constructors

Other invocations of copy constructors

void PassByValue(CPlayer p){}CPlayer ReturnByValue(){

CPlayer p;// ...return p;

}int main(){

CPlayer p;std::vector<CPlayer> vecPlayer(5);vecPlayer.puch_back(p);return 0;

}

(1) Take a class object as the function argument.

(3) Define a non-empty container object.(4) Insert a class object into a container.

(2) Take a class object as the return value.

Page 8: Construction, Destruction, and Assignmentweb.ntnu.edu.tw/~tcchiang/tpp2009/3_Ctor, dtor, and assignment.pdf · Construction, Destruction, and Assignment Instructor: Tsung-Che Chiang

“Ctor, Dtor, and Assignment,”The Practice of Programming, CSIE@NTNU, 200915

Definition & Use of Constructors

We may enforce the provision of necessaryarguments upon the clients.

class CPlayer {public:

CPlayer() { ... } // default ctorCPlayer(const &CPlayer rhs) { ... } // copy ctorCPlayer(const std::string &name, bool isComp) { ... }// ...

private:// ...

};int main(){

CPlayer UncleATu; // not allowed!CPlayer LittleMei(“Mei”, false);CPlayer temp(LittleMei);CPlayer *ptrPlayer = new CPlayer(“PC1”, true);// ...

}

“Ctor, Dtor, and Assignment,”The Practice of Programming, CSIE@NTNU, 200916

Definition & Use of Constructors

In practice, however, we almost always define thedefault constructor if we define at least oneconstructor.

#include <vector>#include <string>

class CPlayer {public:

CPlayer(const std::string &name, bool isHuman) { }};int main(){

std::vector<CPlayer> vecPlayer(5); // default ctor isCPlayer *ptrPlayer = new CPlayer [10]; // required.// ...

}

Page 9: Construction, Destruction, and Assignmentweb.ntnu.edu.tw/~tcchiang/tpp2009/3_Ctor, dtor, and assignment.pdf · Construction, Destruction, and Assignment Instructor: Tsung-Che Chiang

“Ctor, Dtor, and Assignment,”The Practice of Programming, CSIE@NTNU, 200917

Definition & Use of Constructors

We can define a default constructor separately or byproviding default arguments for all parameters.

#include <string>class CPlayer {public:

CPlayer() { }CPlayer(const std::string &name, bool isComp) { }

};

#include <string>class CPlayer {public:

CPlayer(const std::string &name = “”, bool isComp = false){}

};

“Ctor, Dtor, and Assignment,”The Practice of Programming, CSIE@NTNU, 200918

Distinction between CopyConstructor and Copy AssignmentDefinition

Invocation

class CPlayer {public:

CPlayer () { }CPlayer(const CPlayer &rhs) { } // copy ctorCPlayer & operator = (const CPlayer &rhs) // copy assignment{ }

};

int main(){

CPlayer Basic, Posada;CPlayer ARod(Basic), Jeter = Basic;Posada = Basic;return 0;

}

Note. default ctor of CPlayeris invoked for Posada.See “Prefer Initialization to Assignment.”

複製人 vs. 整型

Page 10: Construction, Destruction, and Assignmentweb.ntnu.edu.tw/~tcchiang/tpp2009/3_Ctor, dtor, and assignment.pdf · Construction, Destruction, and Assignment Instructor: Tsung-Che Chiang

“Ctor, Dtor, and Assignment,”The Practice of Programming, CSIE@NTNU, 200919

Distinction between CopyConstructor and Copy Assignment Invocation of copy constructor in the member

initialization list

class CPlayer {public:

CPlayer(const std::string &name,const CMagicItem &item):name_(name)

{magicItem_ = item;

}// ...

private:std::string name_;CMagicItem magicItem_;// ...

};

Note. default ctor of CMagicItemis invoked (if there exists) beforecopy assignment.See “Prefer Initialization to Assignment.”

“Ctor, Dtor, and Assignment,”The Practice of Programming, CSIE@NTNU, 200920

Exercise for Constructors

OutputD1MD2C1NC2PQRSD3C3

Page 11: Construction, Destruction, and Assignmentweb.ntnu.edu.tw/~tcchiang/tpp2009/3_Ctor, dtor, and assignment.pdf · Construction, Destruction, and Assignment Instructor: Tsung-Che Chiang

“Ctor, Dtor, and Assignment,”The Practice of Programming, CSIE@NTNU, 2009

Destructor

“Ctor, Dtor, and Assignment,”The Practice of Programming, CSIE@NTNU, 200922

Use of Destructors

For a class, there can be multiple constructors but atmost one destructor.

The destructor has no parameter and no return type.Not every class needs a destructor.

class CXYZCord {public:

CXYZCord(int x, y, z): x_(x), y_(y), z_(z) {}private:

int x_, y_, z_;};

The above class needs no destructor.

Page 12: Construction, Destruction, and Assignmentweb.ntnu.edu.tw/~tcchiang/tpp2009/3_Ctor, dtor, and assignment.pdf · Construction, Destruction, and Assignment Instructor: Tsung-Che Chiang

“Ctor, Dtor, and Assignment,”The Practice of Programming, CSIE@NTNU, 200923

Use of Destructors

Destructor is usually used to release resource.

class CPlayer {public:

CPlayer(const char name[]){

name_ = new char [strlen(name)+1];strcpy(name_, name);

}~CPlayer(){

delete [] name_;}// ...

private:char *name_;// ...

};

In this example, std::string is better than char *.

“Ctor, Dtor, and Assignment,”The Practice of Programming, CSIE@NTNU, 200924

Exercise

DevC++4992D1D2D3C 9999 <- 2C 8888 <- 3PC 7777 <- 8888A 9999 <- 7777Bye 7777Bye 8888D4Bye 9999Bye 4Bye 3Bye 2Bye 1

VisualC++2005D1D2D3C 9999 <- 2C 8888 <- 3PC 7777 <- 8888Bye 8888A 9999 <- 7777Bye 7777D4Bye 9999Bye 4Bye 3Bye 2Bye 1

9999

88887777

Page 13: Construction, Destruction, and Assignmentweb.ntnu.edu.tw/~tcchiang/tpp2009/3_Ctor, dtor, and assignment.pdf · Construction, Destruction, and Assignment Instructor: Tsung-Che Chiang

“Ctor, Dtor, and Assignment,”The Practice of Programming, CSIE@NTNU, 2009

Guidelines

“Ctor, Dtor, and Assignment,”The Practice of Programming, CSIE@NTNU, 200926

Coding Rules & Guidelines

Know What Functions C++ Silently Writes and Calls. Prefer Initialization to Assignment. Define and Initialize Member Variables in the Same Order. Explicitly Disallow Undesired Compiler-generated

Functions. Prefer the Canonical Form of Assignment. Declare Destructors Virtual in Polymorphic Base Classes. Never Call Virtual Functions during Construction and

Destruction. Copy and Destroy Consistently. Avoid Slicing.

Page 14: Construction, Destruction, and Assignmentweb.ntnu.edu.tw/~tcchiang/tpp2009/3_Ctor, dtor, and assignment.pdf · Construction, Destruction, and Assignment Instructor: Tsung-Che Chiang

“Ctor, Dtor, and Assignment,”The Practice of Programming, CSIE@NTNU, 200927

Exercise for Default Constructor (1)

Are they initialized? No.

“Ctor, Dtor, and Assignment,”The Practice of Programming, CSIE@NTNU, 200928

Exercise for Default Constructor (2)

Are they initialized? The first one is.

Page 15: Construction, Destruction, and Assignmentweb.ntnu.edu.tw/~tcchiang/tpp2009/3_Ctor, dtor, and assignment.pdf · Construction, Destruction, and Assignment Instructor: Tsung-Che Chiang

“Ctor, Dtor, and Assignment,”The Practice of Programming, CSIE@NTNU, 200929

Exercise for Default Constructor (3)

Are they initialized? The second one is.

“Ctor, Dtor, and Assignment,”The Practice of Programming, CSIE@NTNU, 200930

Know What Functions C++ SilentlyWrites and Calls.The compiler may generate the following

functions for you if necessary (and possible).Default constructorCopy constructorDestructorCopy assignment

All these generated functions are publicand inline.

Page 16: Construction, Destruction, and Assignmentweb.ntnu.edu.tw/~tcchiang/tpp2009/3_Ctor, dtor, and assignment.pdf · Construction, Destruction, and Assignment Instructor: Tsung-Che Chiang

“Ctor, Dtor, and Assignment,”The Practice of Programming, CSIE@NTNU, 200931

Know What Functions C++ SilentlyWrites and Calls.Default constructor

It is generated when the class has non-static datamembers with default constructors.

class Comp {public:

Comp() {}// ...};class Car {public:

// ...private:

Comp component_;int price_;

};int main() {

Car mycar;return 0;

}

Note. price_ is not initialized.

Car():component_(){}

“Ctor, Dtor, and Assignment,”The Practice of Programming, CSIE@NTNU, 200932

Know What Functions C++ SilentlyWrites and Calls.Default constructor

It is generated when the class is derived from abase class with the default constructor.

class Car {public:

Car() {}// ...};class BMW : public Car {public:// ...};int main(){

BMW mycar;return 0;

}

Note. Only the Car part is initialized.

BMW():Car(){}

Page 17: Construction, Destruction, and Assignmentweb.ntnu.edu.tw/~tcchiang/tpp2009/3_Ctor, dtor, and assignment.pdf · Construction, Destruction, and Assignment Instructor: Tsung-Che Chiang

“Ctor, Dtor, and Assignment,”The Practice of Programming, CSIE@NTNU, 200933

Know What Functions C++ SilentlyWrites and Calls.Default constructor

Generation of default constructors for the followingCar and BMW classes will fail.

class Comp {public:

Comp(int val) {}// ...};class Car {private:

Comp component_;int price_;

};int main() {

Car mycar; // error!return 0;

}

class Car {public:

Car(int val) {}// ...};class BMW : public Car {// ...};int main(){

BMW mycar; // error!return 0;

}

“Ctor, Dtor, and Assignment,”The Practice of Programming, CSIE@NTNU, 200934

Know What Functions C++ SilentlyWrites and Calls.Default constructor

Generation of default constructors for the followingRefDM and ConstDM classes will fail.

class RefDM {private:

int &refInt_;};int main() {

RefDM r; // error!return 0;

}

class ConstDM {private:

const int VAL_;};int main() {

ConstDM r; // error!return 0;

}

Note. const or reference-type data members must always be initialized in the member initialization list.

Page 18: Construction, Destruction, and Assignmentweb.ntnu.edu.tw/~tcchiang/tpp2009/3_Ctor, dtor, and assignment.pdf · Construction, Destruction, and Assignment Instructor: Tsung-Che Chiang

“Ctor, Dtor, and Assignment,”The Practice of Programming, CSIE@NTNU, 200935

Know What Functions C++ SilentlyWrites and Calls.Default constructor

In the two examples in the previous slide, we needto define the constructor definitely and to use themember initialization list.

class RefDM {public:

RefDM(int &v):refInt_(v) {}?//RefDM(int &v) { refInt_ = v; }private:

int &refInt_;};int main() {

int num;RefDM r(num);return 0;

}

class ConstDM {public:

ConstDM(int v):VAL_(v) {}?//ConstDM(int v) { VAL_ = v; }private:

const int VAL_;};int main() {

ConstDM r(1);return 0;

}

“Ctor, Dtor, and Assignment,”The Practice of Programming, CSIE@NTNU, 200936

Know What Functions C++ SilentlyWrites and Calls.Default constructor

No default constructor is generated by thecompiler for the following two classes.

class OnlyPrimitive {public:

// ...private:

char ch_;int val_;double *ptr_;

};

class HaveSpecificCtor {public:

HaveSpecificCtor(int v);private:

// ...};

Page 19: Construction, Destruction, and Assignmentweb.ntnu.edu.tw/~tcchiang/tpp2009/3_Ctor, dtor, and assignment.pdf · Construction, Destruction, and Assignment Instructor: Tsung-Che Chiang

“Ctor, Dtor, and Assignment,”The Practice of Programming, CSIE@NTNU, 200937

Know What Functions C++ SilentlyWrites and Calls.Copy constructor (Memberwise copy construction)

It is generated when you do not provide it.

class Comp {public:

Comp() {}Comp(const Comp& rhs) { }

// ...};class Car {public:

// ...private:

Comp component_;int price_;

};int main(){

Car mycar1, mycar2(mycar1);return 0;

}

Car(const Car &rhs):component_(rhs.component_),price_(rhs.price)

{}

Call copy ctor of Comp,which is a user-defined class..

Copy each bits since intis a primitive type.

“Ctor, Dtor, and Assignment,”The Practice of Programming, CSIE@NTNU, 200938

Know What Functions C++ SilentlyWrites and Calls.Copy constructor

Is there any problem for the compiler to generatecopy constructor for us?

class RefDM {public:

RefDM(int &v):refInt_(v) {}private:

int &refInt_;};int main() {

int num;RefDM r(num);RefDM r2(r);return 0;

}

class ConstDM {public:

ConstDM(int v):VAL_(v) {}private:

const int VAL_;};int main() {

ConstDM r(1);ConstDM r2(r);return 0;

}

Ans:No.

Page 20: Construction, Destruction, and Assignmentweb.ntnu.edu.tw/~tcchiang/tpp2009/3_Ctor, dtor, and assignment.pdf · Construction, Destruction, and Assignment Instructor: Tsung-Che Chiang

“Ctor, Dtor, and Assignment,”The Practice of Programming, CSIE@NTNU, 200939

Know What Functions C++ SilentlyWrites and Calls.Destructor

It is generated in the same situations as what wehave mentioned for default constructor.

class Comp {public:

~Comp() {}// ...};class Car {public:

// ...private:

Comp component_;int price_;

};int main() {

Car mycar;return 0;

}

class Car {public:

~Car() {}// ...};class BMW : public Car {public:

// ...};int main(){

BMW mycar;return 0;

}

“Ctor, Dtor, and Assignment,”The Practice of Programming, CSIE@NTNU, 200940

Know What Functions C++ SilentlyWrites and Calls.Copy assignment (Memberwise copy assignment)

It is generated when you do not provide it.

class Car {public:

// ...private:

Comp component_;int price_;

};int main(){

Car mycar1, mycar2;mycar2 = mycar1;return 0;

}

Car & operator = (const Car &rhs){

component_ = rhs.component_;price_ = rhs.price_;

}

If Comp does not define the copy assignmentoperator, the compiler will generate it recursively.

Page 21: Construction, Destruction, and Assignmentweb.ntnu.edu.tw/~tcchiang/tpp2009/3_Ctor, dtor, and assignment.pdf · Construction, Destruction, and Assignment Instructor: Tsung-Che Chiang

“Ctor, Dtor, and Assignment,”The Practice of Programming, CSIE@NTNU, 200941

Know What Functions C++ SilentlyWrites and Calls.Copy assignment

Generation of copy assignment operators for thefollowing RefDM and ConstDM classes will fail.

class RefDM {public:

RefDM(int &v):refInt_(v) {}private:

int &refInt_;};int main() {

int num, num2;RefDM r(num), r2(num2);r = r2; // error!return 0;

}

class ConstDM {public:

ConstDM(int v):VAL_(v) {}private:

const int VAL_;};int main() {

ConstDM r(1), r2(2);r = r2; // error!return 0;

}

“Ctor, Dtor, and Assignment,”The Practice of Programming, CSIE@NTNU, 200942

Know What Functions C++ SilentlyWrites and Calls. The compiler-generated copy constructor and copy

assignment do not always work well.class CPlayer {public:

CPlayer(const char name[]) {name_ = new char [strlen(name)+1];strcpy(name_, name);

}~CPlayer() { delete [] name_; }// ...

private:char *name_;// ...

};int main() {

CPlayer p1(“Wade”),p2(p1),p3(“James”);

p3 = p1;}

Example1

Mistakes:1. memory leak2. delete three times (undefined behaviors)(In this example, std::string is better than char *.)

Page 22: Construction, Destruction, and Assignmentweb.ntnu.edu.tw/~tcchiang/tpp2009/3_Ctor, dtor, and assignment.pdf · Construction, Destruction, and Assignment Instructor: Tsung-Che Chiang

“Ctor, Dtor, and Assignment,”The Practice of Programming, CSIE@NTNU, 200943

Know What Functions C++ SilentlyWrites and Calls. The compiler-generated copy constructor and copy

assignment do not always work well.

class CPlayer {public:

CPlayer() {uniqueID_ = NameDatabase_.GetID();

}// ...

private:static CNameDatabase NameDatabase_;int uniqueID_;// ...

};int main() {

CPlayer p1,p2(p1),p3;

p3 = p1;}

Example2

Mistakes:1. ID is no longer unique.2. ID is not re-collected.

“Ctor, Dtor, and Assignment,”The Practice of Programming, CSIE@NTNU, 200944

Know What Functions C++ SilentlyWrites and Calls. The compiler-generated copy constructor and copy

assignment do not always work well. Solutions:

(1) Provide our own copy constructor and copy assignment.(2) Explicitly Disallow Undesired Compiler-generatedFunctions.

Page 23: Construction, Destruction, and Assignmentweb.ntnu.edu.tw/~tcchiang/tpp2009/3_Ctor, dtor, and assignment.pdf · Construction, Destruction, and Assignment Instructor: Tsung-Che Chiang

“Ctor, Dtor, and Assignment,”The Practice of Programming, CSIE@NTNU, 200945

Prefer Initialization to Assignment.

An important concept –the execution of constructorconsists of two stages.

class CPlayer {public:

CPlayer(const std::string &name):name_(name)

{money_ = INIT_MONEY;numLands_ = 0;

}// ...

private:std::string name_;static const int INIT_MONEY = 100000;int money_;int numLands_;// ...

};

Initialization phase

Computation phase

“Ctor, Dtor, and Assignment,”The Practice of Programming, CSIE@NTNU, 200946

Prefer Initialization to Assignment.

Initialize the class-type objects directly is more efficient thancalling default constructors and then setting the values.

class CPlayer {public:

CPlayer(const std::string &name):name_(name),money_(INIT_MONEY),numLands_(0)

{}// ...

private:std::string name_;static const int

INIT_MONEY = 100000;int money_;int numLands_;// ...

};

class CPlayer {public:

CPlayer(const std::string &name){

name_ = name;money_ = INIT_MONEY;numLands_ = 0;

}// ...

private:std::string name_;static const int

INIT_MONEY = 100000;int money_;int numLands_;// ...

};

Page 24: Construction, Destruction, and Assignmentweb.ntnu.edu.tw/~tcchiang/tpp2009/3_Ctor, dtor, and assignment.pdf · Construction, Destruction, and Assignment Instructor: Tsung-Che Chiang

“Ctor, Dtor, and Assignment,”The Practice of Programming, CSIE@NTNU, 200947

Prefer Initialization to Assignment.

Even though the data members are primitive types or need noinitial values, it is more popular to initialize them in the memberinitialization list (for consistency and ease of maintenance.)class CPlayer {public:

CPlayer(const std::string &name):name_(name),money_(INIT_MONEY),numLands_(0),someValue()

{}// ...

private:std::string name_;static const int INIT_MONEY = 100000;int money_;int numLands_;int someValue_;// ...

};

“Ctor, Dtor, and Assignment,”The Practice of Programming, CSIE@NTNU, 200948

Prefer Initialization to Assignment.

When there are multiple constructors, we can move theinitialization of primitive-type data members to one memberfunction to avoid repeating, boring, and error-prone actions.

class CPlayer {public:

CPlayer(const std::string &name):name_(name),money_(INIT_MONEY),numLands_(0),someValue()

{}CPlayer(...)

:name_(name),money_(INIT_MONEY),numLands_(0),someValue()

{}

// ...};

class CPlayer {public:

CPlayer(const std::string &name):name_(name) {

Init();}CPlayer(...)

:name_(name) {Init();

}private:

void Init() {money_ = INIT_MONEY;numLands_ = 0;someValue;

}// ...};

Page 25: Construction, Destruction, and Assignmentweb.ntnu.edu.tw/~tcchiang/tpp2009/3_Ctor, dtor, and assignment.pdf · Construction, Destruction, and Assignment Instructor: Tsung-Che Chiang

“Ctor, Dtor, and Assignment,”The Practice of Programming, CSIE@NTNU, 200949

Prefer Initialization to Assignment.

Name return value optimization is easier forinitialization than for assignment.

class CPlayer{public:CPlayer(int id = 0):id_(id) {

cout << “ctor:" << id_ << endl;}CPlayer(const CPlayer &rhs):id_(rhs.id_){

cout << "copy ctor:" << id_ << endl;}CPlayer & operator= (const CPlayer &rhs){

cout << "copy assignment:" << id_<< " <= " << rhs.id_ << endl;

return *this;}

private:int id_;

};

CPlayer Simple(){

CPlayer local(1);return local;

}int main(){

CPlayer x = Simple();cout << “----------\n”;CPlayer y;y = Simple();

}

Result (DevC++ 4992, VisualC++ 2005)

ctor:1-----------ctor:0ctor:1copy assignment: 0 <= 1

“Ctor, Dtor, and Assignment,”The Practice of Programming, CSIE@NTNU, 200950

Prefer Initialization to Assignment.

Name return value optimization is easier forinitialization than for assignment.CPlayer ComplexFunc(){

CPlayer a(3), b(4);if (true) {

return a;}else {

return b;}

}int main(){

CPlayer x = ComplexFunc();cout << “----------\n”;CPlayer y;y = ComplexFunc();return 0;

}

Result (DevC++ 4992, VisualC++ 2005)

ctor:3ctor:4copy ctor:3-----------ctor:0ctor:3ctor:4copy ctor:3copy assignment: 0 <= 3

Page 26: Construction, Destruction, and Assignmentweb.ntnu.edu.tw/~tcchiang/tpp2009/3_Ctor, dtor, and assignment.pdf · Construction, Destruction, and Assignment Instructor: Tsung-Che Chiang

“Ctor, Dtor, and Assignment,”The Practice of Programming, CSIE@NTNU, 200951

Define and Initialize MemberVariables in the Same Order.

class Employee{public:

Employee(std::string &firstName, std::string &lastName):firstName_(firstName),lastName_(lastName),email_(firstName_ + “.” + lastName_ + “@ntnu.edu.tw”)

{}private:

std::string email_, firstName_, lastName_;};int main(){

Employee wrongEmail(“tc”, “chiang”);return 0;

}

What’s wrong?

“Ctor, Dtor, and Assignment,”The Practice of Programming, CSIE@NTNU, 200952

Define and Initialize MemberVariables in the Same Order. Solution A

Make the order of initialization consistent with the order ofdefinition.

class Employee {public:

Employee(std::string &firstName, std::string &lastName):firstName_(firstN),lastName_(lastName),email_(firstName_ + “.” + lastName_ + “@ntnu.edu.tw”) {}

private:std::string firstName_, lastName_, email_;

};

Page 27: Construction, Destruction, and Assignmentweb.ntnu.edu.tw/~tcchiang/tpp2009/3_Ctor, dtor, and assignment.pdf · Construction, Destruction, and Assignment Instructor: Tsung-Che Chiang

“Ctor, Dtor, and Assignment,”The Practice of Programming, CSIE@NTNU, 200953

Define and Initialize MemberVariables in the Same Order. Solution B

Put the dependent behavior after initialization.

Solution CAvoid the dependent behavior.

class Employee {public:

Employee(std::string &firstName, std::string &lastName):firstName_(firstN),lastName_(lastName){ email_ = firstName_ + “.” + lastName_ + “@ntnu.edu.tw”; }

};

class Employee {public:

Employee(std::string &firstName, std::string &lastName):firstName_(firstN),lastName_(lastName),email_(firstName + “.” + lastName + “@ntnu.edu.tw”) {}

};

“Ctor, Dtor, and Assignment,”The Practice of Programming, CSIE@NTNU, 2009

Exercise

Write a class to simulate std::string.

class String{public:

// 1. default constructor// 2. copy constructor// 3. constructor with one parameter// with type const char *// 4. destructor// 5. size()

private:char *str_;

};

Page 28: Construction, Destruction, and Assignmentweb.ntnu.edu.tw/~tcchiang/tpp2009/3_Ctor, dtor, and assignment.pdf · Construction, Destruction, and Assignment Instructor: Tsung-Che Chiang

“Ctor, Dtor, and Assignment,”The Practice of Programming, CSIE@NTNU, 200955

Explicitly Disallow UndesiredCompiler-generated Functions. As mentioned, the compiler generates copy

constructor and copy assignment automatically for us.In some cases, however, we do not want them.

class CPlayer {public:

CPlayer() {uniqueID_ = NameDatabase_.GetID();

}// ...

private:static CNameDatabase NameDatabase_;int uniqueID_;// ...

};int main() {

CPlayer p1, p2(p1), p3;p3 = p1;

}

“Ctor, Dtor, and Assignment,”The Practice of Programming, CSIE@NTNU, 200956

Explicitly Disallow UndesiredCompiler-generated Functions. Solution: Define copy constructor and copy

assignment definitely and make them private.

class CPlayer {public:

CPlayer() {uniqueID_ = NameDatabase_.GetID();

}// ...

private:CPlayer(const CPlayer &) {}CPlayer & operator = (const CPlayer &) {}static CNameDatabase NameDatabase_;int uniqueID_;// ...

};int main() {

CPlayer p1, p2(p1), p3;p3 = p1;

} Compilation error

Is it completely safe?(Who can invoke the private member functions?)

Page 29: Construction, Destruction, and Assignmentweb.ntnu.edu.tw/~tcchiang/tpp2009/3_Ctor, dtor, and assignment.pdf · Construction, Destruction, and Assignment Instructor: Tsung-Che Chiang

“Ctor, Dtor, and Assignment,”The Practice of Programming, CSIE@NTNU, 200957

Explicitly Disallow UndesiredCompiler-generated Functions. A problem that is not solved by our solution.

class CPlayer {public:

CPlayer() {uniqueID_ = NameDatabase_.GetID();

}void Accident() {

CPlayer p1, p2(p1), p3;p3 = p1;

}// ...

private:CPlayer(const CPlayer &) {}CPlayer & operator = (const CPlayer &) {}static CNameDatabase NameDatabase_;int uniqueID_;// ...

};

Copying is still allowed in the member function(and CPlayer’s friends).

“Ctor, Dtor, and Assignment,”The Practice of Programming, CSIE@NTNU, 200958

Explicitly Disallow UndesiredCompiler-generated Functions. Solution+: Just declare them, but do not define them.

class CPlayer {public:

CPlayer() {uniqueID_ = NameDatabase_.GetID();

}void Accident() {

CPlayer p1, p2(p1), p3;p3 = p1;

}// ...

private:CPlayer(const CPlayer &);CPlayer & operator = (const CPlayer &);static CNameDatabase NameDatabase_;int uniqueID_;// ...

};

Linkage error

Page 30: Construction, Destruction, and Assignmentweb.ntnu.edu.tw/~tcchiang/tpp2009/3_Ctor, dtor, and assignment.pdf · Construction, Destruction, and Assignment Instructor: Tsung-Che Chiang

“Ctor, Dtor, and Assignment,”The Practice of Programming, CSIE@NTNU, 200959

Explicitly Disallow UndesiredCompiler-generated Functions. Solution++: Define a base class to avoid copying.

All copying actions will cause errors during compilation.(It is better to detect the errors earlier.)

class Uncopyable {protected:

Uncopyable() {}~Uncopyable() {}

private:Uncopyable(const Uncopyable &);Uncopyable& operator = (const Uncopyable &);

};class CPlayer : private Uncopyable {

// Do not define copy constructor & copy assignment

};

FAQ1: Why not public or private?

FAQ2: Why not public?

FAQ1: Because we do not want to define Uncopyable objects but want to define CPlayer objects.FAQ2: private inheritance means “is implemented in terms of”, where public inheritance means “is a”.

“Ctor, Dtor, and Assignment,”The Practice of Programming, CSIE@NTNU, 200960

Explicitly Disallow UndesiredCompiler-generated Functions. Summary:

Ensure your class provides correct copying actions,you have the following options: Explicitly disable copying. Explicitly define your own copying functions. Use the compiler-generated version, AND use comments to

let readers know that you do not ignore the above twooptions carelessly.

Note: Copying & standard containers Disable copying implies that you can not put your objects

into standard containers. However, you can still simulate it through the aid of (smart)

pointers.