More notes on “Effective C++”

23 April, 2009 § 1 Comment

This is the fourth post in a series of posts that I started after I finished reading Effective C++ by Scott Meyers. Previously covered were parts three, two, and one.

Item 31: Minimize compilation dependencies between files.
Using the pimpl idiom (“pointer to implementation”) you can truly separate the implementation from the interface. Omaha, aka Google Update, uses the pimpl idiom within the CUP implementation. This allows any client of CupRequest to have a lightweight object and be divorced from implementation details of CupRequest. If CupRequestImpl ever changes, any clients of CupRequest won’t have to recompile, allowing build times to be shorter.

Item 34: Differentiate between inheritance of interface and inheritance of implementation.
The easiest way to differentiate between interfaces and implementations is to declare your interfaces with a naming convention like IInterface. For example, this way you can clearly see that a class is enumerable because it implements IEnumerable, yet if the class inherits SortedArray, then you know that it extends an implementation of a SortedArray.

Item 39: Use private inheritance judiciously.
Sometimes classes have virtual functions that need to be overridden, this should be the only case for using private inheritance. Private inheritance is not the same as public inheritance. Public inheritance is usually referred to as an ‘is-a’ relationship, where you can say that the derived is an extension of the base class. Private inheritance simply tells implementation details, similar to a ‘has-a’ relationship.

Item 48: Be aware of template metaprogramming.
I had never heard of template metaprogramming (TMP) before this Item. This looks to be really interesting, and I’m looking forward to reading C++ Template Metaprogramming written by the Boost organization.

After reading Effective C++, I’m looking forward to using more of the STL, and getting my feet wet with TR1, Boost, and TMP. I would highly recommend reading Effective C++ for an experienced developer that is working in C++. This book is also good for students just getting in to C++, as it can help them watch out for many mistakes that novices and intermediate level developers may make.

More Notes on “Effective C++”

18 April, 2009 § 2 Comments

This is a continuation of a previous post that I started after I finished reading Effective C++ by Scott Meyers.

Item 27: Minimize casting.
It’s hard to minimize casting, so when you do have to cast, you should use the C++-style casts instead of C-style casts. The C++-style casts have distinct purposes and allow the compiler to notice incorrect usage that the C-style casts don’t show.

Item 28: Avoid returning “handles” to object internals.
If you are returning a private member variable by reference from a public function, you’ve just opened up an entry point for that private member variable to be modified without your approval. Anytime you return a private member variable, you should return it by const-reference.

Item 34: Differentiate between inheritance of interface and inheritance of implementation.
The easiest way to differentiate between interfaces and implementations is to declare your interfaces with a naming convention like IInterface. This way you can clearly see that a class is enumerable becuase it implements IEnumerable, yet if the class inherits SortedArray, then you know that it extends an implementation of a SortedArray.

More notes on “Effective C++”

17 April, 2009 § 1 Comment

This is a continuation of a previous post that I started after I finished reading Effective C++ by Scott Meyers.

Item 6: Explicitly disallow the use of compiler-generated functions you do not want.
The recommended way of disallowing the use of compiler-generated functions is to privately declare the copy constructor and assignment operator without providing a definition of them. Omaha, aka Google Update, uses this pattern within their code base by using a macro called DISALLOW_EVIL_CONSTRUCTORS. The macro is called from private visibility.

Item 13: Use objects to manage resources.
Well written code that uses objects to manage resources should not have a single use of the operator delete. Classes like auto_ptr and boost::shared_ptr allow for single ownership of pointers and reference-counted pointers, respectively. Both of these classes will call delete on the contained pointer when it goes out of scope. This is perfect if you are worried about exceptional cases and want to make sure you don’t leak memory.

Item 18: Make interfaces easy to use correctly and hard to use incorrectly.
Enumerated types have an inherent problem associated with them. If you declare an enumerated type, you are not limiting your callers to use only the values within the enumerated type. Take a look at the code sample below:

enum eDayOfWeek { Sunday = 1, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday };
void PrintDayOfWeek( eDayOfWeek eDay );
... //function defintion elided
PrintDayOfWeek( (eDayOfWeek) 75 ); //unexpected behavior here

The way that Meyers handles this is by privately declaring the constructor and publicly declaring static methods that return objects, thus protecting against invalid uses of enumerated types. How does this look:

void PrintDayOfWeek( Day day );
... //function definition elided
PrintDayOfWeek( Day::Monday() );

My Notes on “Effective C++, Third Edition” by Scott Meyers

16 April, 2009 § 3 Comments

I just finished reading Effective C++ by Scott Meyers and it is a great book for anybody that works with C++. Many of the hidden and behind-the-scenes workings in C++ are documented in this book. Unlike most programming books, this one is an enjoyable read, one that I read from cover to cover. In the next few days I’ll be posting notes to some of the Items in the book. Here are the first two:

Item 3: Use const whenever possible.
I had been looking for a chapter like this for a long time, but never got around to finding one until now. Using const in your code makes use of your code much more strict and behave in the way that it was intended to. I take pleasure in showing off my use of const-ness in my code, and for some of the lesser known uses I have this Item to thank for. The most confusing use of const is with pointers to data.

char greeting[] = "hello";
char * const foo = greeting;
const char* const bar = greeting;

In the foo example above, only the pointer is const, greeting can be changed to “goodbye” and the compiler will still be happy. In the bar example, both the pointer and the data are const, meaning that neither can change. The latter is usually what people want.
const should also be applied to iterators of STL container types. If you are performing only a read-only operation on a vector, you should use ::const_iterator instead of ::iterator.

Item 5: Know what functions C++ silently writes and calls.
Unless you explicitly declare a copy constructor and an assignment operator, C++ will implicitly generate one for you. If your class only contains integral types like ints, this usually isn’t a big worry, yet if your class contains pointers, you may want to be scared. The default implementations provided by the C++ compiler will generate shallow copies of the object, meaning that you can end up with two objects pointing at the same block of memory.

Where Am I?

You are currently browsing entries tagged with scott meyers at JAWS.