Article Discussion
Modern C++ Style
Summary: Bjarne Stroustrup talks with Bill Venners about using multiple inheritance and pure abstract classes, multi-paradigm programming, and the technique of resource acquisition is initialization.
14 posts.
The ability to add new comments in this discussion is temporarily disabled.
Most recent reply: October 4, 2005 1:12 AM by Lee
    Bill
     
    Posts: 409 / Nickname: bv / Registered: January 17, 2002 4:28 PM
    Modern C++ Style
    November 23, 2003 9:00 PM      
    Bjarne Stroustrup talks with Bill Venners about using multiple inheritance and pure abstract classes, multi-paradigm programming, and the technique of resource acquisition is initialization.

    Read this Artima.com interview with the creator of C++:

    http://www.artima.com/intv/modern.html
    • Dave
       
      Posts: 4 / Nickname: ramenboy / Registered: November 25, 2003 4:21 PM
      Re: Modern C++ Style
      November 25, 2003 9:51 PM      
      Thanks, I enjoyed this part of the interview.

      I'd like to bring up a couple of points. First, regarding interfaces, Bjarne mentioned that C++ has supported interfaces all along, and he later supported his inclusion of features like multiple inheritance with the argument that, to paraphrase, "Sure, we can simulate this using other features, but sometimes it's nice to have the real thing." It seems like Java has done just that, by making "interface" a language construct; why has C++ not done the same?

      The term "multiparadigm" is an interesting one. It reminds me of Larry Wall's definition of "postmodernism" as applied to programming languages. By his analogy, some languages are "modern", by stressing a particular idea, paradigm, or software model at the expense of (all) others. The "postmodern" language refuses to play favorites, and instead caters to multiple styles.

      Besides C++ (and Perl, of course), another language I see as being somewhat postmodern is Python, because it supports object-oriented programming but does not try to kill procedural or (though this is debatable) functional programming. By supporting first-class, top-level functions, bound methods, and modules as namespaces for both classes and procedures, Python seems to encourage or at least permit a mixing of styles, rather than trying to be pure-OO. I find this ironic because the Python community lately has become rather purist about the Python way, but nonetheless I appreciate that Python allows me to express ideas embodied by multiple paradigms without getting in my way too much, and I appreciate this same quality in C++.

      Bjarne said the following, which made me laugh to myself:
      Object-oriented programming is where you use class hierarchies, as first done by Simula.

      I found this amusing because when I was in college, this statement would have gone without protest. Today, many OO practitioners strongly favor composition and delegance over inheritance and class hierarchies. Systems built using shallow hierarchies, compositional semantics, and reflective and dynamic relationships still seem very OO to me. On the other hand, I have a hard time defining OO anymore, and an even harder time finding public consensus.

      Perhaps Simula (and Smalltalk) are representative of what OO was, in its earlier days, but there are many different, sometimes contradictory views on what OO is today. If we apply the same modern/postmodern criteria, it seems like OO is not modern itself, but that there are many subcategories of OO that exhibit modernist characteristics. For instance, design-by-contract, class-based, prototype-based, statically-typed OO, dynamically-typed OO, and so on.

      C++ clearly supports some of these paradigms (sub-paradigms?) better than others. Even the so-called "multiparadigm" languages have significant tradeoffs to make.

      So long, and thanks to Bill and Bjarne (and the rest of the language designers) for a fascinating series of articles.

      Dave
      • Jon
         
        Posts: 6 / Nickname: talliesin / Registered: November 24, 2003 4:50 AM
        Re: Modern C++ Style
        November 26, 2003 5:32 AM      
        Bjarne mentioned that C++ has supported
        > interfaces all along, and he later supported his inclusion
        > of features like multiple inheritance with the argument
        > that, to paraphrase, "Sure, we can simulate this using
        > other features, but sometimes it's nice to have the real
        > thing." It seems like Java has done just that, by making
        > "interface" a language construct; why has C++ not done the
        > same?

        The question is why should it?

        Interfaces in Java are essentially a reduced form of multiple inheritance. Now in reducing multiple inheritance you make various gains, but if you believe in allowing fuller multiple inheritance to be used then what value is there in having a language feature that duplicates what is possible through using another language feature?
        The only possible advantage would be if the use of multiple inheritance to do what Java interfaces do was so convoluted as to be non-idiomatic. That simply isn't true.
        Arguably Java's interfaces have taught some C++ programmers about this way of using MI, but then so has COM (which is defined almost entirely in terms of interfaces which is most naturally implemented in C++ using MI - though there are other ways, but then there are always "other ways").
        Even so a language feature shouldn't exist to teach you how to use another language feature. Once you have MI the concept of "interfaces" is subsumed into that, you have your interfaces and the job of the language developers is done.
        • Matt
           
          Posts: 62 / Nickname: matt / Registered: February 6, 2002 7:27 AM
          Re: Modern C++ Style
          November 26, 2003 10:49 AM      
          >... but if you believe in allowing
          > fuller multiple inheritance to be used then what value is
          > there in having a language feature that duplicates what is
          > possible through using another language feature?


          Is absolute minimalism the main driving force behind good language design? If that were the case, then why have while, do-while and for, among other things?

          > The only possible advantage would be if the use of
          > multiple inheritance to do what Java interfaces do was so
          > convoluted as to be non-idiomatic. That simply isn't
          > true.


          Doing interfaces in C++ via ABCs seems very clunky compared to the Java interface. It is also more of a convention than a language construct; it is pretty easy to create almost-ABCs, either intentionally or accidentally.

          > Arguably Java's interfaces have taught some C++
          > programmers about this way of using MI...


          I don't really even think of the interface in Java as being multiple inheritance. It seems more like a language construct for objects to advertise what behaviors they support. Nothing it really being inherited; the object has to implement every part of that interface itself. Yes, an object can support more than one interface, but it doesn't really inherit anything from them.

          > ...but then so has
          > COM (which is defined almost entirely in terms of
          > interfaces which is most naturally implemented in C++
          > using MI - though there are other ways, but then there are
          > always "other ways").


          COM is even clunkier than pure C++! The salient point is that the interface in Java is a very clean and simple thing. Yes, COM is built up around interfaces, but COM itself is such a huge complicated, crufty mess, that it is nearly impossible to see the proverbial forest.

          > Even so a language feature shouldn't exist to teach you
          > how to use another language feature.



          Why not?!? What's wrong with language features that help you learn how to be a better programmer? A language feature that does this will probably be more effective at improving programmers than any number of books, articles, mentors or courses.

          The presence of the interface keyword in Java has taught more programmers this concept than anything else, probably. While it is possible to create and use interfaces in C++, it is also possible to program in C++ for many years without ever being keenly aware of the interface concept.
          • Charles
             
            Posts: 4 / Nickname: hawscs / Registered: November 26, 2003 2:22 AM
            Re: Modern C++ Style
            November 26, 2003 0:03 PM      
            > While it is possible to create and use interfaces in C++,
            > it is also possible to program in C++ for many years
            > without ever being keenly aware of the interface concept.

            Quite true. It is also possible to program in C++ for many years without ever being keenly aware of the RAII concept.

            That doesn't seem to address whether or not it is a good idea. I certainly wouldn't object to having an "interface" concept in C++ that embodied the same concepts as an ABC. But the idea that it would be more accessible to novices does not, by itself, seem like sufficient justification.

            I'm not pretending to know the answer, but I do think this is an interesting question:
            Did people learn about interfaces because Java made interfaces a first-class language construct?
            OR
            Did Java make interfaces a first-class language construct because people learned about interfaces using ABC in C++?
          • Jon
             
            Posts: 6 / Nickname: talliesin / Registered: November 24, 2003 4:50 AM
            Re: Modern C++ Style
            November 27, 2003 3:42 AM      
            > >... but if you believe in allowing
            > > fuller multiple inheritance to be used then what value
            > is
            > > there in having a language feature that duplicates what
            > is
            > > possible through using another language feature?

            >
            > Is absolute minimalism the main driving force behind good
            > language design? If that were the case, then why have
            > while, do-while and for, among other
            > things?

            Absolute minimalism the main driving force? No.
            Minimalisim a driving force? I think it should be.

            If an explicit "interface" feature had real advantages (bearing in mind that we already have MI), then maybe it should be added. What are those real advantages?

            > > The only possible advantage would be if the use of
            > > multiple inheritance to do what Java interfaces do was
            > so
            > > convoluted as to be non-idiomatic. That simply isn't
            > > true.

            >
            > Doing interfaces in C++ via ABCs seems very clunky
            > compared to the Java interface. It is also more
            > of a convention than a language construct; it is pretty
            > easy to create almost-ABCs, either intentionally or
            > accidentally.

            Yes it's more of a convention than a language construct. What's wrong with that? I disagree that's it's clunky though.

            I'd defend the ability to give an "interface" class a static member or static member function, or a convenience function defined in terms of the virtual functions:

            class someInterface{
            //it's inherent in our concept of what "someInterface"
            //means that they can be compared and sorted.
            //hence we provide for this:

            virtual int cmp(const someInterface& rhs) = 0;

            //these need not be virtual:

            bool operator==(const someInterface& rhs)const
            {
            return cmp(rhs) == 0;
            }
            bool operator<(const someInterface& rhs)const
            {
            return cmp(rhs) < 0;
            }

            //all "someInterface"s can "process" an array of chars;
            //This isn't far removed from the characters method
            //on a SAX ContentHandler.

            virtual void process(const char* start, const char* end) const = 0;

            //often the user of someInterface has a string (indeed
            //that would be safer. Also, we define process in terms
            //of a sequence (first, last] but many people think of
            //arrays as defined in terms of an initial pointer and a
            //size (especially those who moved from C to C++:

            void process(const char* start, size_t size) const{
            process(start, start + size);
            }

            void process(const std::string& str) const{
            process(str.data(), str.length());
            }

            /*other functions yadda yadda*/
            };


            This isn't to say that you should always do this, and in my example the == and < operators seem a bit doubtful to me.

            However if we wanted to overload process() in a similar manner using virtual functions then we force the simple implementation to be repeated in every class that implements this interface, we gain nothing except for more typing practice and a greater potential for bugs (it's also possible that we'll make things less efficient - my concern here wouldn't be so much efficiency as much as what some developers might do to try to avoid inefficiency).

            > > Arguably Java's interfaces have taught some C++
            > > programmers about this way of using MI...

            >
            > I don't really even think of the interface in Java
            > as being multiple inheritance. It seems more like a
            > language construct for objects to advertise what
            > behaviors they support.

            Inheritance advertises what behaviours a class supports! I think this is a much more important aspect of inheritance, particularly in design stages, than the fact that you can also inherit implementation (and hence program by difference).

            > > ...but then so has
            > > COM (which is defined almost entirely in terms of
            > > interfaces which is most naturally implemented in C++
            > > using MI - though there are other ways, but then there
            > are
            > > always "other ways").

            >
            > COM is even clunkier than pure C++! The salient point
            > is that the interface in Java is a very clean and
            > simple thing. Yes, COM is built up around interfaces,
            > but COM itself is such a huge complicated, crufty mess,
            > that it is nearly impossible to see the proverbial
            > forest.

            Of course COM is clunkier than pure C++, it was an API designed to share objects between a variety of languages - including some with no concept of OO at all - on a variety of operating systems. That's an inherently clunky problem.

            > > Even so a language feature shouldn't exist to teach
            > you
            > > how to use another language feature.

            >
            >
            > Why not?!? What's wrong with language features that
            > help you learn how to be a better programmer? A language
            > feature that does this will probably be more effective at
            > improving programmers than any number of books, articles,
            > mentors or courses.

            Oh, every language feature should teach you how to be a better programmer - it should encourage good programming and discourage bad programming (I love how awkward the new C++ casts are, a little rap across the knuckles every time you cast something). But it should also stand on it's own, otherwise it stops being a good way to learn and becomes "another thing to learn".
            In Java Interface both teaches the technique and stands on it's own. If added to C++ it would only do the former.

            Looking at it another way, do we need a language feature for everything a programmer should learn?

            > The presence of the interface keyword in Java has
            > taught more programmers this concept than anything else,
            > probably. While it is possible to create and use
            > interfaces in C++, it is also possible to program in C++
            > for many years without ever being keenly aware of the
            > interface concept.

            It's possible to program in C++ without being keenly aware of the class concept (every example of C in K&R is valid C++).

            This cuts both ways, C++ adapts to new paradigms well (I think C++ deserves a lot of credit from the way OO has progressed from the earlier definitions - as mentioned by Dave above) and this is partly because it doesn't force much upon the user, but as well as working well with good paradigms and design strategies it will give results to people using dain bramaged paradigms and poor design strategies (not great results, but good enough results that the programmer may continue with a poor methodology for longer than otherwise).

            This isn't a feature that is a requirement of a language, but I'm glad there is a major language that has it to such a large extent.
        • Jon
           
          Posts: 6 / Nickname: talliesin / Registered: November 24, 2003 4:50 AM
          RAII and Java
          November 26, 2003 5:59 AM      
          I don't want to continue comparing Java and C++ (doing so is useful up to a point, but there seems to be plenty of it in these forums), but the mention of RAII in the article along with Dave's comparison of C++ MI and Java interfaces brought something to mind:

          Google currently favours an article of mine when people are searching for RAII, and one thing I noticed looking at my logs are the number of people trying to find a way to use the idiom with Java.
          Now I don't think it's possible (indeed it's my saying it's not possible that makes google match the word "Java" with my article).
          But is there anything one can do with Java other than use finally all over the place? Granted one should design for the two languages differently and not even consider RAII when designing for Java, but I've suddenly found myself with an audience of people who want to do RAII with Java, so if anyone can think of any advice I could pass on I'd be greatful.
          • Charles
             
            Posts: 4 / Nickname: hawscs / Registered: November 26, 2003 2:22 AM
            Re: RAII and Java
            November 26, 2003 0:10 PM      
            I expect you're quite right that there's nothing you can do in Java to improve the situation.

            But here is an interesting trick that C# uses to allow limited RAII. It's far from automatic, but it's certainly better than the situation in Java & other .NET languages.

            using( MyObject o = new MyObject() )
            {
            ... do stuff with o
            }

            The "using" keyword only works if MyObject implements the IDisposable interface. The IDisposable.Dispose method implementation can do the cleanup for MyObject.

            Dispose will be called at the end of the "using" block, whether it leaves by exception or any other mechanism.

            I prefer deterministic destruction like C++ has, but this is a nice attempt to bring RAII to garbage-collected languages.
            • Jon
               
              Posts: 6 / Nickname: talliesin / Registered: November 24, 2003 4:50 AM
              Re: RAII and Java
              November 27, 2003 8:37 AM      
              > But here is an interesting trick that C# uses to allow
              > limited RAII. It's far from automatic, but it's certainly
              > better than the situation in Java & other .NET languages.
              >
              > using( MyObject o = new MyObject() )
              > {
              > ... do stuff with o
              > }
              >


              Not sure if you'd categorise "Managed C++" as a .NET language or as a round non-.NET language being hammered into a square .NET hole... but http://www.codeproject.com/managedcpp/managedraii.asp shows a way to get RAII to work with it.
        • Bjarne
           
          Posts: 48 / Nickname: bjarne / Registered: October 17, 2003 3:32 AM
          Re: Modern C++ Style
          December 1, 2003 8:21 AM      
          > Bjarne mentioned that C++ has supported
          > > interfaces all along, and he later supported his
          > inclusion
          > > of features like multiple inheritance with the argument
          > > that, to paraphrase, "Sure, we can simulate this using
          > > other features, but sometimes it's nice to have the
          > real
          > > thing." It seems like Java has done just that, by
          > making
          > > "interface" a language construct; why has C++ not done
          > the
          > > same?
          >
          > The question is why should it?

          Exactly. I think the positive answer to that question would be "because the concept is easier to teach that way". The negative answer would be "there is no need, Java and C#'s interfaces is just a special case of C++'s multible inheritance". Maybe the best would have been to provide both: C++ provides the most general variant of a concept that fitted into the language, whereas Java and C# arguable provides the most comon case.

          This is an example of a general phenomenon: C++ aims at providing the greatest degree of generality whereas Java and C# aims at providing "Just what you need" (I simplify for claity of expression). My view is that no language designer, however gifted, knows just what the community at large needs so a language design must aim at generality.

          Providing generality often confuses the novice, but comes in handy as we mature as programmers/designers. Providing "the most useful special case (only)" can stiffle programmers after the initial advantage.
          • Kristian
             
            Posts: 4 / Nickname: chryler / Registered: December 2, 2003 5:09 AM
            Re: Modern C++ Style
            December 2, 2003 10:57 AM      
            >Providing "the most useful special case (only)" can stiffle programmers after the initial advantage.

            I agree with this and I really enjoy solving problems with c++ compared to other languages.

            The one possible downside that I see is that when you set your programmers free, they run in different directions. C++ code varies, I find, more than Java and C# code. This is partly because they are young languages but there seems to be more consensus of what the notation should be etc.
            With C++, the way you use libraries varies much more, creating a (less steep) learning curve every time you're introduced to a new library. Take the Spirit library (which I think is absolutely fabulous, by the way. See http://www.boost.org/libs/spirit/). It effectively defines its own syntax and nobody would be able to use it out-of-the-box.
            You could argue that nobody would be able to even if it was defined using conventional function calls and this is true. But in general, I think that learning new libraries is more difficult due to the potential complexity of c++.
            • Jon
               
              Posts: 6 / Nickname: talliesin / Registered: November 24, 2003 4:50 AM
              Re: Modern C++ Style
              December 3, 2003 3:16 AM      
              >Providing "the most useful special case (only)" can stiffle programmers after the initial advantage.

              Or worse, force them into operating at a level lower than the language supports well.
              I've done a lot of code in VB6 (for my sins), and sometimes you have to really fight the language to get something done. And while C++ is a language that will let you shoot yourself in the foot if that's what you tell the compiler to do, VB6 is a language that keeps you safe but where you can convince the compiler that there is no gun there at all (pointers as 32bit integers with normal integer arithmetic semantics).

              Then, having fought the language to get something done that isn't generally possible, or possible within required performance measurements, the temptation is strong to use these kludges every time they might shave off a few cycles.

              (Admittedly I do find these kludges interesting in themselves, though that's no excuse for forcing programmers to use them).

              Take the Spirit library
              > (which I think is absolutely fabulous, by the way. See
              > http://www.boost.org/libs/spirit/). It effectively defines
              > its own syntax and nobody would be able to use it
              > out-of-the-box.
              > You could argue that nobody would be able to even if it
              > was defined using conventional function calls and this is
              > true. But in general, I think that learning new libraries
              > is more difficult due to the potential complexity of c++.

              Hopefully the increasing popularity of the STL will increase the degree to which its conventions are applied to new libraries for other tasks as far as possible, and gradually reduce this factor - while still allowing us to develop other conventions when appropriate of course.
        • Walter
           
          Posts: 12 / Nickname: wkaras / Registered: December 22, 2003 2:53 PM
          Re: Modern C++ Style
          December 24, 2003 10:46 AM      

          > Bjarne mentioned that C++ has supported
          > > interfaces all along, and he later supported his
          > inclusion
          > > of features like multiple inheritance with the argument
          > > that, to paraphrase, "Sure, we can simulate this using
          > > other features, but sometimes it's nice to have the
          > real
          > > thing." It seems like Java has done just that, by
          > making
          > > "interface" a language construct; why has C++ not done
          > the
          > > same?
          >
          > The question is why should it?
          ...


          I would guess that an important reason that the designers of Java went with MI of intefaces only was to avoid the need for virtual base clases. Virtual base classes add some complexity to the way object construction occurs.

          Would anyone disagree that MI of classes is the more natural way to capture the behavior of objects, and, rationalization aside, reducing language complexity is the only real reason to choose single inheritance over multiple?
    • mudit
       
      Posts: 3 / Nickname: mbhandari / Registered: February 22, 2004 5:43 AM
      Re: Modern C++ Style
      February 26, 2004 10:12 PM      
      No doubt C++ is the best programming language,
      thanks to Bjarne
    • Lee
       
      Posts: 3 / Nickname: lpowell / Registered: October 3, 2005 8:06 PM
      Re: Modern C++ Style
      October 4, 2005 1:12 AM      
      An interface keyword would serve a useful purpose if it enabled you to design cast-safe class hierarchies using multiple interface inheritance. By "cast-safe", I mean an inheritance tree such that any object instance can be cast to any of its inherited classes without altering the value of a pointer to that object instance. This is true of single inheritance (whether virtual or not), but not of multiple inheritance in general. Since data members would be banned from interfaces, the interface keyword could be implemented in a manner that would allow all base classes in an object to be referenced from a single pointer. From a debugging standpoint, that would be most reassuring.

      I'm aware that dynamic_cast can be used to cope with MI casting pitfalls, but it's a cure that in my view is worse than the disease. It requires RTTI overhead and sometimes exception handling as well. A project that relies on certain objects that require dynamic_cast while others do not is a nuisance to maintain.