Sie sind auf Seite 1von 25

Effective CPP

Sourabh Agrawal 11-Aug-2011

AGENDA
To suggest a approach to effective way of writing C++ which are more comprehensible, maintainable, portable, extensible, efficient, and likely to behave as you expect .

Topics
Know what functions C++ silently writes and calls Prefer initialization to assignment in constructors List members in an initialization list in the order in which they are declared Prevents Constructor from being used to perform implicit type conversions

Declare a copy constructor and an assignment operator for classes with dynamically allocated memory
Declare destructors virtual in polymorphic base classes

Handle assignment to self in operator=


Have operator= return a reference to *this

Functions C++ silently writes and calls in a Class

class Empty { };

it's essentially the same as if you'd written this:


class Empty { public: Empty() { } ~Empty() { } Empty(const Empty& rhs) { } Empty& operator=(const Empty& rhs) { } };

Prefer initialization to assignment in constructors

Class A { public: A (string initName ) { name = initName; } private: string name; };

Class A { public: A (string initName ): name (initName) { } private: string name; };

and class member variables must be initialized in constructor.

List members in the class in its dependency order

template<class T> class Array { public: Array(int low, int high); size_t size; vector<T> data; int lBound, hBound; };

//Constructor Declaration // No. of elements in array // the array data is stored // lower bound, higher bound

template<class T> Array<T>::Array(int low, int high) : size(high - low + 1), lBound(low), hBound(high), data(size) { }

Prevents Constructor from being used to perform implicit type conversions

class ABC { public: ABC(int x) { } }; void function(ABC Object) { cout<<Function Called<<endl; } int main() { function ( 1 ) ; return 0; }

class ABC { public: explicit ABC(int x) // Not allowing implicit casting of integer to ABC { } }; void function(ABC Object) { cout<<Function Called<<endl; } int main() { function ( 1 ) ; return 0; }

//passing a integer data type

Declare a copy constructor and an assignment operator for classes with dynamically allocated memory

class String { char *data; public: String::String(const char *value) { if (value) { data = new char[strlen(value) + 1]; strcpy(data, value); } } String::~String() { delete [] data; } }; int main() { String a("Hello"); { String b("World"); b = a; } String c = a; return 0; }

Bitwise Copying

Bitwise Copying

String a("Hello"); String b("World");

b = a;

// Both b and a data* are pointing to same memory location Memory Leak

delete a

Leads to Memory Corruption

Declare destructors virtual in polymorphic base classes

Acc. to C++ Standard: When you try to delete a derived class object through a base class pointer and the base class has a non-virtual the results are undefined.

Polymorphic base classes should declare virtual destructors. If a class has any virtual functions, it should have a virtual destructor. Classes not designed to be base classes or not designed to be used polymorphically should not declare virtual destructors.

Handle assignment to self in operator=

If you can detect an assignment to self at the top of your assignment operator(s), you can return right away, possibly saving a lot of work that you'd otherwise have to go through to implement assignment A more important reason for checking for assignment to self is to ensure correctness.

Have operator= return a reference to *this

Prevent exceptions from leaving destructors


Destructors should never emit exceptions. If functions called in a destructor may throw, the destructor should catch any exceptions, then swallow them or terminate the program. If class clients need to be able to react to exceptions thrown during an operation, the class should provide a regular (i.e., non-destructor) function that performs the operation.

Never call virtual functions during construction or destruction


Don't call virtual functions during construction or destruction, because such calls will never go to a more derived class than that of the currently executing constructor or destructor.

Thank You !!!


References: Effective C++ C++ Standard Draft

Das könnte Ihnen auch gefallen