Summary
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:

In Part I: Multiple Inheritance and Interfaces,
Meyers indicates how his view of multiple inheritance has changed with time, describes
the C++ community's take on Java's interface, and points out a schism in
the focus of the C++ and other prominent development communities.

In this week's installment,
Meyers discusses 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.

Say What You Mean

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.