14

I read somewhere in one of the answers to a question here (can't remember which) that C++ is not suitable for object-oriented programming. There was some mentioning that you could make use of its feature or something like that, but not in a purely OOP sense (I actually didn't really understand what the person meant).

Is there some truth in this; if so, why?

gablin
  • 17,525

12 Answers12

31

As described at So what *did* Alan Kay really mean by the term "object-oriented"?, Alan Kay thought that message-passing was the important bit of OOP, but it's the bit that "C with classes" (which later became C++) lacks. C++ is just structs with a bit of behaviour, whereas objects in Smalltalk or Objective-C are "intelligent" in that they can decide what they do with the messages they're sent. If a Smalltalk-esque object receives a message it doesn't have an implementation for, it could lazily add one, forward the message to another object, or do any arbitrary thing.

What C++ offers in the way of object-orientation is virtual methods and polymorphism involving the way those methods are invoked. When the compiler sees a data type (or class) that has virtual methods, it constructs a vtable with a slot for each virtual method. Subclasses that implement the virtual methods will put their implementations in the correct slots, so client code merely needs to know where in the virtual table to look for the code to run rather than resolving it all the way down to the specific function. What this means is that C++ effectively does have a form of multiple dispatch, though it's all implemented in the compiler and isn't as capable as a Smalltalk-esque system.

If you take message-passing as fundamental to OOP, then while you can do it with C++ it's far from easy. OTOH if you take OOP to mean associating data with functions that act on that data, C++ is fine.

27

This kind of discussion bothers me because it sounds like exegesis, people debating the meaning of Holy Scriptute, or the American Constitution, and what the original author(s) meant, as if what we think doesn't matter.

Look, Alan Kay was/is a smart guy, and he had a good idea, that rubbed up against a bunch of other good ideas, and found its realization in Smalltalk and other languages.

He is not the Messiah, and OOP is not the One True Programming Paradigm.

It is a good idea, among many. Does C++ have good ideas in it, coming from the OOP mindset? Of course it does.

Mike Dunlavey
  • 12,905
9

C++ supports OOP, if you define OOP to mean encapsulation, inheritance and polymorphism.

However, C++ doesn't really excel at OOP. One reason is that polymorphism often depends on heap-allocated objects, which, (notwithstanding the use of smart pointers), are more natural to work with in a garbage-collected language.

Where C++ excels, however, is in generic-programming. C++ allows you to easily create highly-efficient, generic code through template-based functional programming techniques.

5

C++ borrowed OOP features from Simula. One or more of the Simula developers IIRC commented that C++ isn't what they had in mind.

C++ has good tools for abstraction, but it's more a mixed-paradigm language than an object oriented language. The object oriented features are there, but you have choices that aren't "strict OOP".

One of the naughty "opt-outs" you get in C++ is to use early rather than late binding for methods. Not only is this possible - it's the default. In Java, "final" is related, but cleaner in some ways (it specifies intent in a way that isn't just about avoiding a trivial performance overhead), and it's not the default.

In some ways, C++ shows signs of being an early experiment that's still here. Even so, it's still a good tool, with a lot of advantages that you don't get in other OOP languages.

4

Forcing everything to be part of a class does not necessarily yield great OO code.

Ask a poor procedural programmer to program in Java and they will possibly take a class somewhere, give it a static main method and stick 1000 lines of code in it. I know I have seen it.

Java has a switch statement. I have seen switch( type ) { case typeA: bundles_of_code; break; case typeB: bundles_of_other_code; break } etc. in both C++ and Java code.

C++ supports many OO concepts but its standard is not defined by it, however I guess a lot depends on what your objective is.

The main "poor" semantic in C++ is allowing copy-construction of classes whereby an object transmogrifies into another one. You can disable this but then you cannot return one from a function. Fortunately this is addressed in C++0x.

CashCow
  • 1,630
3

OOP is not just about making sure everything is of or is in a class. It's perfectly possible to write non-OO code in a "purely OO" language. For example, "main" is often pointed out as being a global function, but inventing a class solely to contain a static main method is just as non-OO.

C++ works best with a mix of various things; this shouldn't be surprising, as that's how most good things work best. Often OOP is one of those very useful tools.

Fred Nurk
  • 845
2

C++ can be used for OOP but it is not as 'pure' as something like Smalltalk. C++ also lets you do non-OOP which is what people may be talking about.

Craig
  • 4,272
2

Although I disagree with the sentiment, it is true that C++'s type system is not pure OOP -- not "everything is an object." Numbers (in particular) cannot be extended as readily as they can in, say, Smalltalk. You cannot redefine the meaning of "2+2" for instance (although you could redefine the meaning of "two + two").

But what most people probably mean is that many people write non-object oriented code in C++ but believe that because they're using an "OOP" language, they're object-oriented. That's not true. But in my opinion, you can write hideous imperative code in Smalltalk and not be any superior to a decent OOP design in C++.

Larry OBrien
  • 5,037
1

In my view, it's not so much a definitional issue as a usability issue.

Objects are an abstraction intended to make it easier to read, write, and reason about complex programs. For a practical programmer, whether a language meets all the criteria of a particular formal definition of "object-oriented" (there seem to be several competing ones!) isn't really as important as whether the tools it offers are suitable for thinking about your program in terms of said objects -- i.e., actually reaping the supposed productivity benefits of OOP.

In C++, objects are a terribly leaky abstractions, often forcing programmers to wrangle with nasty issues related to how those objects are structured in memory -- issues that are more reminiscent of coding in straight C than other OOP languages. For example, C++ Frequently Questioned Answers offers this criticism (among others):

It is very beneficial for a practitioner to gain familiarity with OO systems other than C++, and with OO definitions other than the "encapsulation, inheritance, polymorphism" trinity interpreted in special ways allowing C++ to be considered "OO". For example, a claim that an environment lacking boundary checking or garbage collection is not an OO environment sounds outrageous to people accustomed to C++. But from many perspectives, it makes a lot of sense. If anyone can overwrite an object, where's the "encapsulation"? If disposing an object can lead to dangling references or memory leaks, how is the system "object-oriented"? What about the ability to tell what kind of object is located at a given place and time? You say the software works with objects - where are they? And if one can't find out, how is one supposed to debug the software?

C++ is object-oriented, but unpleasantly and incompletely: its users have to devote a lot of effort to making sure their data actually behaves like "real" objects rather than errant bits. That said, lots of code has been written in C++ over its lifespan, most of it making use of classes and dynamic dispatch, so it's self-evidently something that you can use for practical OOP.

Alex P
  • 123
  • 1
  • 5
1

Alan Kay's perfectly valid objection to C++ was that it was a macro language on top of C.

The notion of "message passing" is simply the idea that instances of classes are held in memory and that they expose methods which can be called. Message passing is *simulated" in C++ using vtables holding pointers to functions.

To say that message passing does not exist in C++ is inaccurate, what's more accurate to say is that message passing is an integral part of other languages likes smalltalk and Java because the language is not preprocessing a foreign construct and grafting it on C directly.

This is a highly semantic language design argument which I suspect is a little beyond the experience level of the questioner.

That being said there are a thousand reasons to hate C++, and very few reasons to love it.

Rather than looking for the perfect hammer and the perfect nail, find the perfect house to build and then find the right tools...that takes experience.

Its also important to remember that in systems programming what Alan Kay fears is not "pure OOP" is actually a strength of C++. To each his own...

bobx
  • 11
  • 2
-1

There is a reason Graham Lee had the most upvotes here. To reiterate, it appears that a C++ class is not really an object in the sense that it does not perform message passing. I think this is what trips people up a great deal when they are learning C++ or oop. People are told object oriented is 'this' and then told that C++ does it differently. Well C++ never did OOP differently. If you think this way you'll never appreciate C++ classes for what they are meant for and that is that they are merely an improvement upon the procedural paradigm by incorporating abstraction, and dynamic behavior. So C++ classes are fundementally procedural, they just improve upon the procedural paradigm, or rather they are a more advanced version of a C struct.

-1

Steve Yegge said it best:

C++ is the dumbest language on earth, in the very real sense of being the least sentient. It doesn't know about itself.

The object system in C++ is so hard-wired and fixed at compile time, that it's very distant from the original notion of OOP that involves message-passing, introspection, reflection, dynamic dispatch, and late binding, among other things. The only thing C++ and Smalltalk have in common are a bit of vocabulary.