Presentation is loading. Please wait.

Presentation is loading. Please wait.

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

Similar presentations


Presentation on theme: "Effective C++, 2nd Ed. By Scott Myers. Constructors, Destructors, and Assignment Operators 11.Define a copy constructor and an assignment operator for."— Presentation transcript:

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

2 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=.

3 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

4 12. Prefer initialization to assignment in constructors. const member functions must be initialized private: 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

5 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.

6 13. List members in an initialization list in the order in which they are declared. private: apvector data; int length; } template Array ::Array() :length(10), data(length) // ERROR - length undefined {}

7 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&);

8 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++

9 16.Assign to all data members in operator=. When adding data members to an existing class, don’t forget to update constructors & operator=.

10 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;

11 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.

12 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

13 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

14 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

15 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

16 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

17 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.

18 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

19 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!

20 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

21 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”

22 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?

23 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.

24 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

25 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!

26 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!!

27 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

28 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 { … };

29 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

30 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.

31 37. Never redefine a inherited non-virtual function. Schizophrenic behavior class 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.

32 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

33 45. Know what functions C++ silently writes and calls. Copy Constructor Destructors Address-of operators

34 48. Pay attention to compiler warnings. Compiler writers have a better grasp of what is going on than you

35


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

Similar presentations


Ads by Google