50 Effective Ways to improve Your Programs and Design in C++

Shifting from C to C++:

Prefer const and inline to #define
Prefer to iostream to stdio.h
Prefer new and delete to malloc and free.
Prefer C++ style comments.

Memory Management:

Use the same form in corresponding uses of new and delete.
Use delete on pointer members on destructions.
Be prepared for Out Of Memory conditions.
Adhere to convention when writing operator new and operator delete.
Avoid hiding the “normal” form of new.
Write operator delete if you write operator new.

Constructors, Destructors, and Assignment Operators:

Declare a Copy Constructor and an assignment operator for classes with dynamically allocated memory.
Prefer initialization to assignment in constructors.
List members in an initialization list in the order in which they are declared.
Make Destructors virtual in Base classes.
Have operator = return a reference to *this.
Assign to all data members in Operator=.
Check for assignment to self in operator= .

Classes and Functions - Design and Declaration:

Strive for class interfaces that are complete and minimal
Differentiate among member functions,non-member functions and
friend functions.
Avoid data members in public interface.
Use const whenever possible.
Prefer pass-by-reference to pass-by-value.
Don’t try to return a reference when you must return on object.
Choose carefully between function overloading and parameter defaulting.
Avoid overloading on a pointer and a numerical type.
Guard against potential ambiguity.
Explicitly disallow use of implicitly generated member functions you don’t want.
Partition the global namespace.

Classes and Functions - Implementations:

Avoid returning “handles” to internal data.
Avoid member functions that return non-const pointers or references to members less accessible than themselves.
Never return a reference to a local object or to a dereferenced pointer initialized by new within function.
Postpone variables definitions as long as possible.
Use inlining judiciously.
Minimize compilation dependencies between files.

Inheritance and Object-Oriented Design:

Make sure public inheritance model “isa”
Differentiate between inheritance of interface and inheritance of implementation.
Never redefine an inherited nonvirtual function.
Never redefine an default parameter value
Avoid casts down the inheritance hierarchy.
Model “has -a” or “is-implemented-in-terms-of” through layering.
Differentiate between inheritance and templates.
Use private inheritance judiciously.
Use multiple inheritance judiciously.
Say what you mean:underastand ehat you’re saying.

Miscellaneous:

Know what functions C++ silently writes and calls.
Prefer compile-time and link-time errors to runtime errors
Ensure that non local static objects are initialized before they are used.
Pay attention to compiler warnings.
Familiarize yourself with standard library.
Improve your understanding of C++.

ref:

Effective C++ by Scott Meyers

Pointers : Deciphering Pointer Declarations

Deciphering Pointer Declarations

Pointers are known to be a very difficult programming concept for beginners to understand and master .They are also a well-known cause of many programming bugs for both novice and experienced programmers. Pointers are cognitively difficult to understand in part because of the level of indirection that they introduce.

Ever came across a declaration like int * (* (*fp1) (int) ) [10]; or something similar that you couldn't fathom? Sometimes people get confused when more stars are thrown in. Below right-left rules are the key to read , which will allow you to interpret any C/C++ declaration accurately.

Right-Left Rules to follow for deciphering pointer declarations. These are particularly important for function pointers:-

1. Start with the name that will identify the pointer, which is known as the identifier.

2. Move to the right until you encounter a right-parentheses [symbol = ")" ] or reach the end. Do not stop if the () brackets are used to pass parameters to a function. Also do not stop on encountering brackets used with arrays: [ ].

3. Now go left of the identifier to continue deciphering the declaration. Keep going left until you find a left-parentheses [the symbol "(" ] or reach the end. Do not stop if the brackets are used to pass parameters to a function.

4. The whole interpretation should be a nice long sentence.

Here are a few examples to make the process clear:

1. int *ptr[4]

ptr is an array of size 4... [nothing more on the right]
...of pointers to an int. [nothing more to read]

2. int (*ptr) [4]

ptr is... [ the) indicates:"stop reading further to the right". Now read left.]
...a pointer to... [we encounter a ( . Now read further right.]
...an array of size 4... [nothing more on right]
...of type int. [nothing more on left]

3.

( * f1 ( ) ) ( )
1 2 3 4 5 6

f1 is a function…. [ we see a },character 5. Now read left]
[ The arguments in () at position 4 should be read as one character.
Do not stop at () that pass parameter to a function.]
…returning a pointer… [we see a (,character 1. now read right.]
…to a function… [nothing more on right]
…returning an int [not specified,but implicit]

4.

float ( * f1 ) ( )
1 2 3 4 5 6

f1 is … [we see a),character 5,so go left now]
…a pointer… [we see a (,character 2,so go right now]
…to a function… [nothing more on right,so go left now]
…returning a float. [nothing more on left]

5.

float * ( * f1 [5] ) ( )
1 2 3 4 5 6 7 8

f1 is an array of 5… [ we see character 7,so go left]
…pointers… [we see character 3,so go right]
…to a function… [nothing more on right, so go left]
…returning a pointer to float. [nothing more on left]


ref :