Home > Guides > Programming > C/C++

The Rise & Fall of Object Orientation

Last updated Sep 10, 2004.

Slowly but surely, state-of-the-art C++ programming is becoming less and less object-oriented. No, C++ isn't falling back to procedural programming -- quite to the contrary. However, if you examine standard C++ libraries (such as STL, , reference_warapper and just about any other recent addition to the language), you will notice that the traditional concepts of object-oriented programming have fallen from grace, replaced by more advanced paradigms and techniques.

It wouldn't be an exaggeration to say that classic object-orientation is now a thing of the past. Today, I will discuss this paradigm shift and its causes.

Traditional Object-Oriented Concepts

The roots of object orientation date back to the late 1960s, when languages such as Modula-2 implemented dynamic binding, encapsulation, and inheritance. Later programming languages (particularly Smalltalk 72) refined these concepts, forming a new paradigm called "object-oriented programming." If anything, OOP focused on the ability to define autonomous units that bundle data and related operations as an object. Many of the early OO languages relied on dynamic typing: virtual functions, inheritance and the ability to pick and mix properties of multiple objects at runtime.

As always, proponents of the new paradigm promised a higher level of code reuse, resilience to design changes, safety, reliability and portability. Indeed, if you compare antiquated programming languages such as Fortran and COBOL to Smalltalk, OO has fulfilled these promises to some extent. Yet today, more than a decade after the revolution that made OO a predominant programming paradigm, traditional OO programming is a disappointment. Diplomatic understatements and lip-service won't change this fact. Let's see why OO programming has lost its luster in C++.

Code Reuse

Code reuse was OOP's biggest promise. Pundits claimed that by using virtual member functions and inheritance, you could get the ultimate level of code reuse while still benefiting from resilience to design changes. In practice, though, this software design model has resulted in a large number of extremely inefficient frameworks and libraries.

Take MFC for example. Its set of collection classes is light years behind STL. The problem isn't with MFC, though. Similar frameworks, say OWL and National Institute of Health Class Library (NIHCL), repeated exactly the same design mistakes: deriving every collection class from an abstract collection class and relying on virtual member functions and dynamic typing. This suggests that OO itself is the culprit, not the designers.

Member Functions

Member functions (or methods, as they are called in other programming languages) are a fundamental aspect of OOP. Think for minute: What could be more logical and properly designed than a member function that is familiar with the intimate details of its object?

Obvious advantages not withstanding, member functions are disfavored in state-of-the-art C++ libraries. The problem is that a member function is useful only for a single class. This is the bane of code reuse. Think, for example, of a library of containers. If each container class defines its own size() member function, you will end up writing numerous size() functions that basically do the same thing.

The alternative is to define a generic function (let's call it an algorithm to make it more palatable for hard core OO aficionados) that works for every container type. Isn't this a step backwards into the good old days of procedural programming, where data structures and functions that manipulated them were kept apart? Syntactically speaking -- yes. Generic programming looks like procedural programming more than object-oriented programming. Yet under the hood, things work very differently. A generic algorithm, unlike a typical function in a procedural language, knows very little about the data structure it manipulates. Furthermore, it doesn't peek into the data structure directly but uses iterators for this purpose. So the syntactic similarity is misleading.

Should member functions be thrown out of the window? Not quite. They are useful under the following conditions: when the language forces you to use a member function (constructors, destructors and conversion operators for example), or when the member function implements a service that is meaningful only in the context of a certain class. An example of this is a connect() member function of a socket class. In most other cases, experience has shown that common operations such as insert(), assign(), replace(), sort(), and copy() , which are applicable to a very wide set of objects, are best implemented as freestanding algorithms rather than being replicated as a member function in every class.

Inheritance

Another holy cow of traditional OO design is inheritance. STL hardly uses inheritance; it seems that the newer a C++ library is, the less it uses inheritance. Why?

In theory at least, inheritance is the primary means of reuse. However, it incurs a lot of complications and overhead. First, every class hierarchy that relies on inheritance must have a virtual destructor and virtual functions. For certain abstractions, such as C++ streams, this model is used effectively. Yet, in other abstractions such as containers, there's little motivation to derive container classes from a common base class.

Inheritance incurs another onerous problem: it propagates bugs. A faulty member function in a base class contaminates every derived class. Even if the base class' functions are bug-free, derived classes often carry the excess baggage inherited from their base classes. Look at cout, for example. How many programmers ever bother to use the numerous member functions that the ios_base and basic_ios base classes pass on to them?

By forgoing inheritance, STL containers don't carry such excess baggage. Furthermore, the fact that every container class is independent enables implementers to optimize each of them.

Conclusions

One trick that OO diehards use is to broaden its definition. They claim that a through and through OO language should provide facilities for generic programming and functional programming in addition to the traditional OO concepts. Under this broad definition, the recent additions to the Standard Library still follow the OO model. However, this is just a verbal maneuver that is meant to camouflage the real facts: OO in its classic sense is a thing of the past, at least in C++. Experience has shown that generic programming and to a smaller extent, functional programming, achieve a high level of code reuse, portability and efficiency.

Books

Exceptional C++ Style, by Herb Sutter, contains a systematic analysis of class std::string. Sutter shows that the majority of its member functions can actually be replaced with existing STL algorithms, at least in theory. He also provides plenty of reasons why this approach is better. The four mini-chapters dedicated to this issue are indispensable for anyone who is interested in learning how general purpose libraries should be designed today. It's surprising to see that the original notions of OOP such as inheritance, virtual functions and member functions have become so antiquated and cumbersome in the last 10 years. Undoubtedly, were class std::string to be re-designed from scratch today, it would offer a cleaner, slimmer and more consistent interface

.

Discussions

What is Required of a Move Constructor
Posted Jul 18, 2010 09:52 AM by alex14637
2 Replies
Bugzilla
Posted Nov 18, 2008 01:53 AM by cupu
2 Replies
i want c++ book through net
Posted Aug 23, 2007 11:13 PM by harivilu
3 Replies

Make a New Comment

You must log in in order to post a comment.

Related Resources

Danny KalevYves Smith: Suspicions that The Fed is manipulating Wall Street
By Danny KalevMay 24, 2010 No Comments

Yves Smith, the nom de plume of the creator of Naked Capitalism and one of the most savvy and respected members of the blogosphere. In professional life Yves is known as Susan Webber. Yves recently gave an interview to an Israeli financial newspaper in which she claims that a federal team unofficially called "the plunge protection team" is manipulating the stocks on Wall Street.

Danny KaleviPhone OS 4.0 SDK License Controversy
By Danny KalevApril 17, 2010 1 Comment

The much-discussed software development kit for the upcoming iPhone OS 4.0 says that native applications must be "originally written" in Objective C, C, or C++", forbidding developers from using any sort of "translation or compatibility layer." This legalese seems to rule out just about anything you can think of -- translating an application written in any other language to C++. However, this stern interpretation is probably exaggerated. Besides, when you consider the outcry and criticism with which Apple's license was greeted, you can't help but wondering where all these freedom of expression activists were when Sun -- and later Microsoft and Google -- imposed similar draconian restrictions on developers.

Danny KalevBjarne Stroustrups's Stevens Talk
By Danny KalevDecember 7, 2009 No Comments

On 2nd December Bjarne Stroustrup delivered a talk about the standardization process of C++0x at the Stevens institute. Here some of the key points from his talk.

See More Blogs

Informit Network