35
Effective C++, 2nd Ed. By Scott Myers

Effective C++, 2nd Ed. By Scott Myers. Constructors, Destructors, and Assignment Operators 11.Define a copy constructor and an assignment operator for

Embed Size (px)

Citation preview

Page 1: Effective C++, 2nd Ed. By Scott Myers. Constructors, Destructors, and Assignment Operators 11.Define a copy constructor and an assignment operator for

Effective C++, 2nd Ed.

By Scott Myers

Page 2: Effective C++, 2nd Ed. By Scott Myers. Constructors, Destructors, and Assignment Operators 11.Define a copy constructor and an assignment operator for

Constructors, Destructors, and Assignment Operators

11.Define a copy constructor and an assignment operator for classes with dynamically allocated memory.

12.Prefer initialization to assignment in constructors.

13.List members in an initialization list in the order in which they are declared.

14.Make destructors virtual in base classes.

15.Have operator= return a reference to *this.

16.Assign to all data members in operator=.

17. Check for assignment to self in operator=.

Page 3: Effective C++, 2nd Ed. By Scott Myers. Constructors, Destructors, and Assignment Operators 11.Define a copy constructor and an assignment operator for

11. Define a copy constructor and an assignment operator for classes with

dynamically allocated memory.

• Why? Otherwise– Copy Constructors

• result in two pointers to the same memory block

– Assignments• cause memory leaks• result in two pointers to the same memory block

– Unexpected problems can occur

– See BadString.cpp

Page 4: Effective C++, 2nd Ed. By Scott Myers. Constructors, Destructors, and Assignment Operators 11.Define a copy constructor and an assignment operator for

12. Prefer initialization to assignment in constructors.

• const member functions must be initializedprivate: const string name;

• It is more efficient– With layered objects, only a single member function

(the constructor) is called, not two(the default constructor, then operator=).

– See initializeNo.cpp, initializeYes.cpp

Page 5: Effective C++, 2nd Ed. By Scott Myers. Constructors, Destructors, and Assignment Operators 11.Define a copy constructor and an assignment operator for

13. List members in an initialization list in the order in which they are declared.

• Class data members are initialized in the order of their declaration in the class.

• The order in which they are listed in a member initialization list does not change above.

• It can be misleading to reorder the list.

Page 6: Effective C++, 2nd Ed. By Scott Myers. Constructors, Destructors, and Assignment Operators 11.Define a copy constructor and an assignment operator for

13. List members in an initialization list in the order in which they are declared.

private: apvector<T> data;

int length;

}

template<class T>

Array<T>::Array()

: length(10), data(length) // ERROR - length undefined

{}

Page 7: Effective C++, 2nd Ed. By Scott Myers. Constructors, Destructors, and Assignment Operators 11.Define a copy constructor and an assignment operator for

15. Have operator= return a reference to *this.

• Allows chaining of assignments (consistent with built-in types)

• The correct signature for assignment operators:C& C::operator=(const C&);

Page 8: Effective C++, 2nd Ed. By Scott Myers. Constructors, Destructors, and Assignment Operators 11.Define a copy constructor and an assignment operator for

15. Have operator= return a reference to *this.

• The signature: const C& C::operator=(const C&);

• prevents assignments such as C a,b,c;

:

(a = b) = c;

• but this is incompatible with built-in types int i,j,k;

:

(i = j) = k; // OK in C++

Page 9: Effective C++, 2nd Ed. By Scott Myers. Constructors, Destructors, and Assignment Operators 11.Define a copy constructor and an assignment operator for

16. Assign to all data members in operator=.

• When adding data members to an existing class, don’t forget to update constructors & operator=.

Page 10: Effective C++, 2nd Ed. By Scott Myers. Constructors, Destructors, and Assignment Operators 11.Define a copy constructor and an assignment operator for

17. Check for assignment to self in operator=.

• For dynamically allocated data, the delete will destroy what is supposed to be copied.

// check for assignment to self

if (this == &rhs) return *this;

Page 11: Effective C++, 2nd Ed. By Scott Myers. Constructors, Destructors, and Assignment Operators 11.Define a copy constructor and an assignment operator for

Classes & Functions: Design & Declaration

18. Strive for class interfaces that are complete and minimal.

19. Differentiate among member functions, global functions and friend functions.

20. Avoid data members in the public interface.

21. Use const whenever possible.

22. Pass and return objects by reference instead of by value.

23. Don't try to return a reference when you must return an object.

Page 12: Effective C++, 2nd Ed. By Scott Myers. Constructors, Destructors, and Assignment Operators 11.Define a copy constructor and an assignment operator for

18. Strive for class interfaces that are complete and minimal.

• Class interface goals– Easy to understand

– Straightforward to use

– Easy to implement

– Powerful

– Convenient to use

• Competing goals

• Complete– allows clients to do

anything they might reasonably want to do

• Minimal– As few functions in it

as possible

– No overlapping functionality

Page 13: Effective C++, 2nd Ed. By Scott Myers. Constructors, Destructors, and Assignment Operators 11.Define a copy constructor and an assignment operator for

18. Strive for class interfaces that are complete and minimal.

• More functions, harder for users to understand– by expanding functionality to make the class more

attractive, you may discourage use

• A large interface can lead to confusion– you have think( ), some prefer ponder( ) so you add it

– other users wonder if there is a subtle difference

• A large interface is hard to maintain– Duplicate bugs, more documentation

Page 14: Effective C++, 2nd Ed. By Scott Myers. Constructors, Destructors, and Assignment Operators 11.Define a copy constructor and an assignment operator for

18. Strive for class interfaces that are complete and minimal.

• On the other hand, don’t be unduly miserly

• You may justify more than a minimal set of functions– A commonly performed function may be performed more

efficiently as a member function

– A member function may make the class substantially easier to use

– A member function may prevent client errors

Page 15: Effective C++, 2nd Ed. By Scott Myers. Constructors, Destructors, and Assignment Operators 11.Define a copy constructor and an assignment operator for

19. Differentiate among member functions, global functions and friend functions.

• Virtual functions must be members

• operator>> & operator<< are never members

• Only non-member functions get their type conversions on their left-most argument Rational r = 2 * Rational(3,4);

operarator* must be Friend or auxiliary function

• Everything else should be member functions

Page 16: Effective C++, 2nd Ed. By Scott Myers. Constructors, Destructors, and Assignment Operators 11.Define a copy constructor and an assignment operator for

20. Avoid data members in the public interface.

• Consistency– If everything is a function., clients won’t have to remember whether

or not to use ( )

• Control– You have precise control over data members– You can implement r/w access

• Functional Abstraction– You can replace data member w/ computation later

Page 17: Effective C++, 2nd Ed. By Scott Myers. Constructors, Destructors, and Assignment Operators 11.Define a copy constructor and an assignment operator for

21. Use const whenever possible.

• Const allows you to specify a semantic constraint -- a particular object should not be modified -- and compilers will enforce it

• Whenever that is true, say so explicitly.

Page 18: Effective C++, 2nd Ed. By Scott Myers. Constructors, Destructors, and Assignment Operators 11.Define a copy constructor and an assignment operator for

Const & Pointers

char *p = “Hello”; //non-const ptr

//non-const data

const char *p = “Hello”; //non-const ptr

//const data

char * const p = “Hello”; //const ptr

//non-const data

const char * const p = “Hello”; //const ptr

//const data

void f1(const Widget *pw);

void f2(Widget const *pw); // both valid

Page 19: Effective C++, 2nd Ed. By Scott Myers. Constructors, Destructors, and Assignment Operators 11.Define a copy constructor and an assignment operator for

More on Const

const Rational operator*(const Rational& lhs,

const Rational& rhs);

Rational a, b, c;

...

(a * b) = c; // illegal for built-in types

• Declaring operator*’s return value as const is the Right Thing To Do!

Page 20: Effective C++, 2nd Ed. By Scott Myers. Constructors, Destructors, and Assignment Operators 11.Define a copy constructor and an assignment operator for

Const Member Functions

• The purpose of const member functions – is to specify which member functions may be invoked on

const objects.

const Rational operator*(const Rational& lhs,

const Rational& rhs);

Rational a, b, c;

...

(a * b) = c; // illegal for built-in types

Page 21: Effective C++, 2nd Ed. By Scott Myers. Constructors, Destructors, and Assignment Operators 11.Define a copy constructor and an assignment operator for

22. Pass and return objects by reference instead of by value.

• The meaning of passing an object by reference is defined by the copy constructor.

• Efficient– particularly with derived classes

• Avoids “the slicing problem”

Page 22: Effective C++, 2nd Ed. By Scott Myers. Constructors, Destructors, and Assignment Operators 11.Define a copy constructor and an assignment operator for

23. Don't try to return a reference when you must return an object.

const Rational operator*(const Rational& lhs,

const Rational& rhs);

• Couldn’t this function be optimized to:const Rational& operator*(const Rational& lhs,

const Rational& rhs);

• NO– what reference would you return

• a local variable?

• a value you constructed?

• a dynamically allocated object?

Page 23: Effective C++, 2nd Ed. By Scott Myers. Constructors, Destructors, and Assignment Operators 11.Define a copy constructor and an assignment operator for

Class Design & Implementation Inheritance & Miscellany

27. Explicitly disallow use of implicitly generated member functions you don’t want.

30. Avoid member functions that return non-const pointers or references to members less accessible than themselves.

32. Postpone variable definitions as long as possible.

42. Use private inheritance judiciously.

45. Know what functions C++ silently writes and calls.

48. Pay attention to compiler warnings.

Page 24: Effective C++, 2nd Ed. By Scott Myers. Constructors, Destructors, and Assignment Operators 11.Define a copy constructor and an assignment operator for

27. Explicitly disallow use of implicitly generated member functions you don’t want.

• Writing Array class you want to disallow assignment (as in built-in arrays)

• How do you disallow it?

– Don’t write it? No good, C++ will write one for you

• Solution:– declare operator= a private member function

• How do you keep member and friend functions from calling it?– Never define the function

– The user will get an error at link-time

Page 25: Effective C++, 2nd Ed. By Scott Myers. Constructors, Destructors, and Assignment Operators 11.Define a copy constructor and an assignment operator for

30. Avoid member functions that return non-const pointers or references to members

less accessible than themselves.

class Address { … };

class Person {

public:

Address& personAddress() { return address };

...

Private:

Address address;

};

Person scott(...);

Address& addr = scott.personAddress();

// address is no longer private!!

// Pointers will do the same!

Page 26: Effective C++, 2nd Ed. By Scott Myers. Constructors, Destructors, and Assignment Operators 11.Define a copy constructor and an assignment operator for

32. Postpone variable definitions as long as possible.

• Some programmers always define their vars at the beginning of a block (e.g., main block).

• Is this a good practice?– Constructor executes when control reaches variable’s definition.

– Destructor executes when goes out of scope

– If a variable is used only in an if block, the constructor/desctructor must still be executed

– There is a cost associated with unused variables

• NO!!

Page 27: Effective C++, 2nd Ed. By Scott Myers. Constructors, Destructors, and Assignment Operators 11.Define a copy constructor and an assignment operator for

32. Postpone variable definitions as long as possible.

• Also, postpone the definition until you have initialization arguments for it

• Avoids pointless default constructions

• Combine decent variable names with contextually meaningful arguments,

• Then you have a good argument for eliminating some comments

Page 28: Effective C++, 2nd Ed. By Scott Myers. Constructors, Destructors, and Assignment Operators 11.Define a copy constructor and an assignment operator for

36. Differentiate between inheritance of interface and inheritance of implementation.

Class Shape

{

public:

virtual void draw() const = 0; // pure virtual

virtual void error(const string& msg); // virtual

int objectID() const; // non-virtual

};

class Rectangle: public Shape{ … };

class Ellipse : public Shape { … };

Page 29: Effective C++, 2nd Ed. By Scott Myers. Constructors, Destructors, and Assignment Operators 11.Define a copy constructor and an assignment operator for

36. Differentiate between inheritance of interface and inheritance of implementation.

• Member function interfaces are always inherited

• The purpose of a pure virtual function is to have derived classes inherit a function interface only

• The purpose of declaring a simple virtual function is to have derived classes inherit a function interface as well as a default implementation

• The purpose of declaring a non-virtual function is to have derived classes inherit a function interface as well as a mandatory implementation

Page 30: Effective C++, 2nd Ed. By Scott Myers. Constructors, Destructors, and Assignment Operators 11.Define a copy constructor and an assignment operator for

37. Never redefine a inherited non-virtual function.

• A non-virtual function identifies an invariant over specialization.

• Redefinition will result in objects that exhibit schizophrenic behavior.

Page 31: Effective C++, 2nd Ed. By Scott Myers. Constructors, Destructors, and Assignment Operators 11.Define a copy constructor and an assignment operator for

37. Never redefine a inherited non-virtual function.

• Schizophrenic behaviorclass B {

public:

void mf();

};

class D: public B { … };

D x;

B *pB = &x; D *pD = &x;

pB->mf(); pD->mf();

…Same object, but will not behave same way if mf is non-virtual and D

has defined its own version of mf.

Page 32: Effective C++, 2nd Ed. By Scott Myers. Constructors, Destructors, and Assignment Operators 11.Define a copy constructor and an assignment operator for

42. Use private inheritance judiciously.

• What is private inheritance?– Members inherited from a private base class become private

members of the derived class

• Private inheritance means– is-implemented-in-terms-of NOT is-a– implementation only inherited, not interface

• Use layering (containment) when you can, private inheritance when you must

Page 33: Effective C++, 2nd Ed. By Scott Myers. Constructors, Destructors, and Assignment Operators 11.Define a copy constructor and an assignment operator for

45. Know what functions C++ silently writes and calls.

• Copy Constructor

• Destructors

• Address-of operators

Page 34: Effective C++, 2nd Ed. By Scott Myers. Constructors, Destructors, and Assignment Operators 11.Define a copy constructor and an assignment operator for

48. Pay attention to compiler warnings.

• Compiler writers have a better grasp of what is going on than you

Page 35: Effective C++, 2nd Ed. By Scott Myers. Constructors, Destructors, and Assignment Operators 11.Define a copy constructor and an assignment operator for