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
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 virtual functions.
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
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
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
interface is. 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
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
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
interface-like classes that have no data, you will
be able to side-step most of those difficulties. So I'm less down
on multiple inheritance now.
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
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
forced 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
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: