Sponsored Link •
Scott Meyers, C++ expert and author of numerous books, including Effective C++, talks with Bill Venners about the importance of saying what you mean and understanding what you say, the three fundamental relationships between classes, and the difference between virtual and non-virtual functions.
Scott Meyers is one of the world's foremost experts on C++ software development. He wrote the best-selling Effective C++ series (Addison-Wesley): Effective C++ (1997), More Effective C++ (1995), and Effective STL (2001); wrote and designed the Effective C++ CD; is consulting editor for Addison-Wesley's Effective Software Development Series; and is a member of the advisory board for Software Development magazine. A programmer since 1972, Meyers holds an M.S. in computer science from Stanford University and a Ph.D. from Brown University.
In this four-part interview, which is being published in weekly installments, Meyers gives his views on many object-oriented design topics:
interface, and points out a schism in the focus of the C++ and other prominent development communities.
Bill Venners: One guideline you include in Effective C++ is, "Say what you mean; understand what you're saying." You make the point that it's not enough to understand language syntax. You have to understand what you mean when you use the syntax. Why do you think that is important?
Scott Meyers: You are communicating with two different parties
when you write a program: the compiler and other human beings. The language behaves
in particular ways because constructs have certain kinds of meaning. For example, when I
say public inheritance means IS-A—as in an
ArrayList IS A
List—that is reflected in the language's explicit conversion rules. If
you're trying to make public inheritance mean something other than IS-A, you're then
fighting the language, because it will probably perform conversions that your semantic
model would not normally allow. If you want to represent something using a language
mechanism, and you don't understand to what the language mechanism corresponds, the
language will not enforce the rules that you want enforced for the particular semantics
that you need. One reason understanding meaning is important, therefore, is you are
communicating with the compiler and you don't want to fight the language. You want the
language to work for you and back up your semantics.
You also want to communicate with other human beings. As a human being, if I'm reading your code and I see that a class publicly inherits from that class, I will think, "This is an IS-A relationship." If that's not what you meant, I'll be confused. Or if I see a non-virtual member function, I will think, "This is an invariant. Nobody should ever override this." If I see it has been overridden in a derived class, I see a contradiction in your design. I no longer trust my understanding of your design, because I'm getting conflicting pieces of information. That makes it more difficult for me to understand what your program is supposed to do. So meaning is important because first, you don't want to ascribe semantics to a language feature that are different from what the compiler will enforce. And second, you don't want to miscommunicate what you're trying to express to other people who read your code.