Sponsored Link •
Scott Meyers, C++ expert and author of numerous books including Effective C++, talks with Bill Venners about multiple inheritance and
Scott Meyers is one of the world's foremost experts on C++ software development. He wrote the best-selling Effective C++ series (Effective C++, More Effective C++, and Effective STL), 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, he holds an M.S. in Computer Science from Stanford University and a Ph.D. from Brown University.
In this four-part interview, which will be published in weekly
installments, Meyers gives his views on many topics of
object-oriented design, including the use of multiple inheritance
in light of Java's
interface, designing minimal and
complete interfaces, public data members and contracts, and the
const. In this initial installment, 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 of focus between
the C++ and other prominent development communities.
Bill Venners: Your book Effective C++
was the first book on object-oriented programming that I bought,
and I picked up a lot of fundamentals from it. For example, I had
never heard of ISA (as in an
ArrayList IS A
List) before reading your book. Your guideline, "Make
sure public inheritance models ISA" was my first introduction to
that idea. I probably hadn't even heard that data should be private
before reading your book.
I read Effective C++ back in the early 90s, when I was
moving from C to C++. Much of my philosophy of object-oriented
design originally came from your book, but since then I've changed
the way I think about design in some ways. I'm curious how your
ideas of object-oriented design may have changed or evolved since
you wrote Effective C++. My first question for you
involves multiple inheritance and
Any time you used the word "judiciously" in an Effective C++ guideline it really scared me away. For example, you said, "Use private inheritance judiciously." I didn't just use private inheritance judiciously, I never used it at all. You said, "Use multiple inheritance judiciously." In five years of C++ programming, I never once used multiple inheritance.
My attitude about multiple inheritance in C++ didn't come only from your book. Most of my friends who were programming in C++ shared that attitude. The way we thought about multiple inheritance was that given two full blown classes, each of which could be instantiated, you create a third full blown class that inherits from the other two. That class structure, which is what we thought of when we thought of multiple inheritance, has all the problems you describe in Effective C++. I wasn't determined to avoid multiple inheritance in C++ at all costs, but in five years I never encountered a situation in which I felt inheriting from multiple base classes made sense in my designs.
When I moved from C++ to Java in early 1996, however, I
interface. I quickly learned the
mechanics of Java's
interface—I understood how it
worked—but I didn't know how to design with it. Here was multiple
inheritance again, but not the full blown kind of multiple
inheritance I was used to in C++. With Java's
interface construct, I could multiply inherit
interface but not implementation. In the C++ terminology you used
in Effective C++, Java only let me multiply inherit from
abstract base classes (ABCs) that had no data members and only pure
Bill Venners: Why did Java only allow multiple
inheritance of interface? How should I apply
interfaces in Java designs? I didn't know, but I did
soon realize that although in five years of C++ I never once used
multiple inheritance, I was finding Java's special kind of multiple
inheritance very useful. The process of struggling with Java's
interface changed the way I think about
object-oriented design in general. Were I to go back to C++ now, I
would make much more use of ABCs that have no data members and only
pure virtual functions.
I'm curious if you've had any similar transformation regarding multiple inheritance. Is there anything you would say about ABCs or multiple inheritance and their place in designs now that you didn't say 10 years ago?
Scott Meyers: I don't have a lot that is new,
but I would say two things. First, if you look at
interfaces in Java or .NET, in addition to being ABCs,
interfaces also have no data. I have come to
appreciate that if you use abstract base classes and eliminate any
data from them, then a lot of the difficulties of multiple
inheritance that I wrote about just go away, even in C++.
I happen to think one of the contributions of Java was getting
rid of some of the baggage that comes with multiple inheritance in
C++. I'm guessing, since I'm not a Java guy, that the creators of
Java looked at the multiple inheritance model of C++. They said,
"This has some good things, but it has some baggage too. So we're
going to try to find a way to have the good stuff and throw away
the baggage." That's essentially what an
It is an abstract base class that doesn't have any of the things
that tend to give rise to trouble in C++, because it doesn't have
any data. I think that's an interesting idea. So I think
interfaces are an interesting idea.
Second, at the time in 1991 when I wrote that multiple inheritance guideline in Effective C++, a huge debate about multiple inheritance was raging in the C++ community. My advice to use multiple inheritance judiciously was based on two observations. First, at that particular time no one had really come out with a compelling example in which multiple inheritance was useful and there was no competing design that was at least as good. Second, even some of the people who had used multiple inheritance didn't have great things to say about it. Notably, Jerry Schwartz, who had implemented the IO streams library based on multiple inheritance, had publicly said that if he had it to do over again he would not use multiple inheritance. He would find some way to get rid of the multiple inheritance.
At the time I wrote that guideline in 1991 I had never seen a
compelling example for the use of multiple inheritance. I knew
about the difficulties with multiple inheritance that I have
written about. At the time I was not talking about
interfaces, because they didn't exist in that name.
And somebody like Jerry, who had a lot of experience with multiple
inheritance, was saying if he had to do it over again he would have
found a way to get rid of the multiple inheritance. That was the
reason for my advice about multiple inheritance at that time.
A certain amount of time has gone by. My feeling about multiple
inheritance now is that as long as you go into it with your eyes
open, so you understand the kinds of things I wrote about in the
book, especially if you are using
classes that have no data, you will be able to side-step most of
those difficulties. So I'm less down on multiple inheritance
Frankly, though, my advice would not change. I would still say
use multiple inheritance judiciously, because if you have a choice
between a single inheritance based design and a multiple
inheritance based design, I think most of the time the single
inheritance based design will be simpler. And I like simpler better
than more complicated. But perhaps you are faced with a multiple
inheritance based design and a single inheritance based design, and
the multiple inheritance based design strikes you as being cleaner
or in some other way advantageous. As long as you've taken into
account the difficulties with multiple inheritance that have been
talked about, probably you've eliminated them by using
interface classes, then I would say fine, follow your
design instinct and use the multiple inheritance. So my tone on
multiple inheritance has softened a little bit.
Bill Venners: If public inheritance means ISA, what does ABC inheritance mean?
Scott Meyers: ABC inheritance still means ISA. Public inheritance always means ISA. That's just what it means. If you are inheriting from an ABC, all you are saying is, "I'm going to inherit an interface, and that particular interface can never be instantiated." But in C++ there can still be data in the ABC, and there are certainly going to be virtual member functions, so you still have behavior. Publicly inheriting from an ABC just means that every instance of my class IS AN instance of this ABC. That's what the inheritance is asserting. That's what ISA means. "I am one of those." The fact that the base class is an ABC says, "By myself, I am not complete enough to be instantiated." But those are orthogonal statements.
Bill Venners: Let's define ABC. ABC means abstract base class. So what would you call in C++ that special case of an ABC that has no data and nothing but pure virtual functions, which have no implementation.
Scott Meyers: The C++ community does not have a
name for that. There is no commonly accepted term for that kind of
class. Some people call it "interface class." Some people quite
incorrectly call it a virtual base class, but as long as we are
among friends and know what we are talking about, that's OK. But
the notion of essentially a C++ implementation of an
interface in Java or C# does not have a name in
Bill Venners: I found in coming to Java that
interfaces are a very useful tool in designs. Were I
to go back to C++, I would use them a lot more. That's how
I would now use multiple inheritance in C++.
Bill Venners: Interface classes, or whatever
you want to call them. I am wondering to what extent the C++
community has discovered this usefulness that I feel
interfaces provide in Java. I see it as something
that's generically useful in object-oriented design. The fact that
Java had a special construct called
me to figure out what to do with it in 1996. That's how I
discovered this useful tool of OO design. But if the C++ community
doesn't have a special name for it, then maybe that community
really hasn't been turned on by
Scott Meyers: I think two things have happened. First, experienced designers of frameworks and libraries had already decided that that particular kind of abstract base class was particularly useful. They were using them. They just didn't have a particular name for them. Second, in the past last five or six years, almost all of the attention in the C++ community has been focused on two features of the language: exceptions and templates. Templates and the standard template library (STL) have received a huge amount of attention. As a result, the object-oriented part of the language has not received very much attention. If I had to give a reason why there doesn't seem to be a common name for interface classes in the C++ community, I would say probably the most important reason is simply because the entire language community has been focused so much more on these other features, exceptions and templates, that they did not know how to use.
I'm going to speculate now, because I haven't been watching Java and I've just got my feet a little bit wet in .NET. But I would say that while the C++ community was focusing on templates, the STL, and exceptions—oddly enough the three are wrapped up together pretty closely—what they were not doing was component-based development. For example, there is no huge collection of class libraries for C++. The standard library for C++ is pretty impoverished. In the meantime, the rest of the world was busy creating huge class libraries that let you write all kinds of really neat applications without having to write very much code. Certainly Java is famous for its libraries. .NET has a huge number of libraries.
I think a schism existed between the C++ community, which was still focused on language issues, and the other prominent development communities, which pretty much left the language alone. Java already had exceptions, but didn't have templates and had nothing like the STL. Yet the Java community focused on writing a whole bunch of libraries that everybody can assume will exist everywhere, libraries that will let you write applications really quickly. The end result is, we have templates in C++, but there's no way to write user interfaces or talk to databases. Java has no templates, but you can write user interfaces up the wazoo and you can talk to databases with no trouble at all.
Effective C++, Second Edition, by Scott Meyers is at
More Effective C++, by Scott Meyers is at Amazon.com
Effective STL, by Scott Meyers is at Amazon.com at:
Effective C++ CD, by Scott Meyers is at Amazon.com
Scott Meyer's website contains links to many publications,
presentations, books, and other information from Scott:
Images of Persephone, the best dog in the world: