tags:

views:

847

answers:

15

I find myself always trying to fit everything into the OOP methodology, when I'm coding in C/C++. But I realize that I don't always have to force everything into this mold. What are some pros/cons for using the OOP methodology versus not? I'm more interested in the pros/cons of NOT using OOP (for example, are there optimization benefits to not using OOP?). Thanks, let me know.

+4  A: 

A benefit of non-oop functionality is that it often makes exporting your functionality to different languages easier. For example a simple DLL containing only functions is much easier to use in C#, you can use the P/Invoke to simply call the C++ functions. So in this sense it can be useful for writing extremely time critical algorithms that fit nicely into single/few function calls.

DeusAduro
+19  A: 

Of course it's very easy to explain a million reasons why OOP is a good thing. These include: design patterns, abstraction, encapsulation, modularity, polymorphism, and inheritance.


When not to use OOP:

  • Putting square pegs in round holes: Don't wrap everything in classes when they don't need to be. Sometimes there is no need and the extra overhead just makes your code slower and more complex.
  • Object state can get very complex: There is a really good quote from Joe Armstrong who invented Erlang:

The problem with object-oriented languages is they’ve got all this implicit environment that they carry around with them. You wanted a banana but what you got was a gorilla holding the banana and the entire jungle.

  • Your code is already not OOP: It's not worth porting your code if your old code is not OOP. There is a quote from Richard Stallman in 1995

Adding OOP to Emacs is not clearly an improvement; I used OOP when working on the Lisp Machine window systems, and I disagree with the usual view that it is a superior way to program.

  • Portability with C: You may need to export a set of functions to C. Although you can simulate OOP in C by making a struct and a set of functions who's first parameter takes a pointer to that struct, it isn't always natural.

You may find more reasons in this paper entitled Bad Engineering Properties of Object-Oriented Languages.

Wikipedia's Object Oriented Programming page also discusses some pros and cons.

Brian R. Bondy
+1, not only slower but harder to read
hasen j
I do agree with the answer: it can be slower, but doesn't need to be! But why is it harder to read (if you know the language - But non-OOP code is harder to read as well if you don't now the language.)? I mean: looking at OOP-code is like watching education videos for children: You got a class A playing around with class B whose purpose is to control class C and so on.. In non-OOP you got functions calling other function in an endless amount of complexity, so that you have to understand everything before changing anything. (in OOP you just need to understand the module you're working on).
Dane
I agree, I use OOP every chance I get. My focus was to find counter reasons though. You may be making a small function to do something that is self contained though, and in cases like that there is no need to wrap it in a class, make a constructor, make a destructor, ...
Brian R. Bondy
Just to nitpick, your "easy" reasons why OOP is a good thing aren't really so easy: design patterns -- exist largely because of the major shortcomings of OOP languages. Many of them simply become irrelevant in other paradigms. It's not obvious how inheritance is a good thing *in itself*. Abstraction, encapsulation and modularity are not exclusive to OOP, but exist in most paradigms I know of. Similarly, most paradigms have some form of polymorphism as well, even if the implementation is different than the OOP one.
jalf
And the decision not to use OOP depends heavily on what alternatives exist. OOP sounds pretty attractive if it's compared to traditional procedural C code. But if the alternative is functional programming, it's a much harder sell. It's not "OOP or nothing" as OOP proponents often make it out to be. Usually, it's OOP or some other powerful paradigm.
jalf
jalf: Good point, it is often compared to procedural only and not things like functional programming.
Brian R. Bondy
+7  A: 

One school of thought with object-oriented programming is that you should have all of the functions that operate on a class as methods on the class.

Scott Meyers, one of the C++ gurus, actually argues against this in this article:

How Non-Member Functions Improve Encapsulation.

He basically says, unless there's a real compelling reason to, you should keep the function SEPARATE from the class. Otherwise the class can turn into this big bloated unmanageable mess.

Based on experiences in a previous large project, I totally agree with him.

Andrew Shepherd
did the OP ask how to convert functional based programs to object oriented programs?
Breton
@Breton: No, I was just trying to establish the definition of object oriented programming that I was working with for my post.
Andrew Shepherd
Rather, I can kind of see where your going, but the wording of your answer is kind of misleading.
Breton
Much better. +1
Breton
It's more like, there are classes of classes. Some classes are there to just store data. They should only know about the data they model, have getters and setters and not much more.And then there should be classes that operate on these data classes: Import a model from a file, export a model to a file, print a report, etc. So it's like separating the procedural aspect from the data modelling aspect to a certain degree, but it turns out to be very useful. But I would still keep the procedural parts as parts of a class, and not stick them into functions.
Carsten Kuckuk
I wouldn't paint Scott as a C++ _object-oriented_ guru.
sbi
@sbi - OK, I put that there for impact, but you're right. I've taken it out.
Andrew Shepherd
+1  A: 

It is a very project dependent decision. My general feel of OOP is that its useful for organizing large projects that involve multiple components. One area I find that OOP is especially pointless is school assignments. Excepting those specifically designed to teach OOP concepts, or large software design concepts, many of my assignments, specifically those in more algorithmy type classes are best suited to non-OOP design.

So specifically, smaller projects, that are not likely to grow large, and projects that center around a single algorithm seem to be non-OOP candidates in my books. Also, if you can write the specification as a linear set of steps, e.g., with no interactive GUI or state to maintain, this would also be an opportunity.

Of course, if you're required to use an OOP design, or an OOP toolkit, or if you have well defined 'objects' in you're spec, or if you need the features of polymorphism, etc. etc. etc...there are plenty of reasons to use it, the above seem to be indicators of when it would be simple not to.

Just my $0.02.

Daniel Brotherston
A: 

In my mind it comes down to what kind of model suits the problem at hand. It seems to me that OOP is best suited to coding GUI programs, in that the data and functionality for a graphical object is easily bundled together. Other problems- (such as a webserver, as an example off the top of my head), might be more easily modeled with a data centric approach, where there's no strong advantage to having a method and its data near each-other.

tl;dr depends on the problem.

Breton
A: 

I'd say the greatest benefit of C++ OOP is inheritance and polymorphism (Virtual function etc...) . This allows for code reuse and extendibility

dtroy
A: 

C++, use OOP - - - C, no, with certain exceptions

In C++ you should use OOP. It's a nice abstraction and it's the tool you are given. You either use it or leave it in the box where it can't help. You don't use the power saw for everything but I would read the manual and have it ready for the right job.

In C, it's a more difficult call. While you can certainly write arbitrarily object-oriented code in C, it's enough of a pain that you immediately find yourself fighting the language in order to use it. You may be more productive dropping the doesn't-fit-so-well design pattern and programming as C was intended to be used.

Furthermore, every time you make an array of function pointers or something in an OOP-in-C design pattern, you sever almost completely all visible links in the inheritance chain, making the code hard to maintain. In real OOP languages, there is an obvious chain of derived classes, often analyzed and documented for you. (mmm, javadoc.) Not so in OOP-in-C, and the tools available won't be able to see it.

So, I would argue in general against OOP in C. For a really complex program, you may well need the abstraction, and then you will have to do it despite needing to fight the language in the process and despite making the program quite hard to follow by anyone other than the original author.

But if you knew the program was going to become that complicated, you shouldn't have written it in C in the first place...

DigitalRoss
A: 

In C, there are some times when I 'emulate' the object oriented approach, by defining some sort of constructor with granular control over things like callbacks, when running several instances of it.

For instance, lets say I have some spiffy event handler library and I know that down the road I'm going to need many allocated copies:

So I would have (in C)

MyEvent *ev1 = new_eventhandler();

set_event_callback_func(ev1, callback_one);
ev1->setfd(fd1);

MyEvent *ev2 = new_eventhandler();

set_event_callback_func(ev2, callback_two);
ev2->setfd(fd2);

destroy_eventhandler(ev1);
destroy_eventhandler(ev2);

Obviously, I would later do something useful with that like handle received events in the two respective callback functions. I'm not going to really elaborate on the method of typing function pointers and structures to hold them, nor what would go on in the 'constructor' because its pretty obvious.

I think, this approach works for more advanced interfaces where its desirable to allow the user to define their own callbacks (and change them on the fly), or when working on complex non-blocking I/O services.

Otherwise, I much prefer a more procedural / functional approach.

Tim Post
+1  A: 

Having an Ada background, I develop in C in terms of packages containing data and their associated functions. This gives a code very modular with pieces of code that can be taken apart and reused on other projects. I don't feel the need to use OOP.

When I develop in Objective-C, objects are the natural container for data and code. I still develop with more or less the package concept in mind with some new cool features.

mouviciel
A: 

Probably an unpopular idea but I think you should stick with non-OOP unless it adds something useful. In most practical problems OOP is useful but if I'm just playing with an idea I start writing non-object code and put functions and data into classes if it becomes useful.

Of course I still use other objects in my code (std::vector et al) and I use namespaces to help organise my functions but why put code into objects until it is useful? Equally don't shy away from free functions in an OO solution.

Patrick
+2  A: 

OOP is used a lot in GUI code, computer games, and simulations. Windows should be polymorphic - you can click on them, resize them, and so on. Computer game objects should be polymorphic - they probably have a location, a path to follow, they might have health, and they might have some AI behavior. Simulation objects also have behavior that is similar, but breaks down into classes.

For most things though, OOP is a bit of a waste of time. State usually just causes trouble, unless you have put it safely in the database where it belongs.

wisty
+2  A: 

I suggest you read Bjarne's Paper about Why C++ is not just an Object-Oriented Programming Language

Fred
+2  A: 

If we consider, for a moment, not object-orienatation itself but one of the keystones of object-orientation: encapsulation.

It can be shown that change-propagation probability cannot increase with distance from the change: if A depends on B and B depends on C, and we change C, then the probability that A will change cannot be larger than the proabability that B will change. If B is a direct dependency on C and A is an indirect dependency on C, then, more generally, to minimise the potential cost of any change in a system we must miminimise the potential number of direct dependencies.

The ISO defines encapsulation as the property that the information contained in an object is accessible only through interactions at the interfaces supported by the object.

We use encapsulation to minimise the number of potential dependencies with the highest change-propagation probability. Basically, encapsulation mitigates the ripple effect.

Thus one reason not to use encapsulation is when the system is so small or so unchanging that the cost of potential ripple effects is negligible. This is also, therefore, a case when OO might not be used without potentially costly consequences.

Ed Kirwan
+1  A: 

Well, there are several alternatives. Non-OOP code in C++ may instead be:

  • C-style procedural code, or
  • C++-style generic programming

The only advantages to the first are the simplicity and backwards-compatibility. If you're writing a small trivial app, then messing around with classes is just a waste of time. If you're trying to write a "Hello World", just call printf already. Don't bother wrapping it in a class. And if you're working with an existing C codebase, it's probably not object-oriented, and trying to force it into a different paradigm than it already uses is just a recipe for pain.

For the latter, the situation is different, in that this approach is often superior to "traditional OOP".

Generic programming gives you greater performance (among other things because you often avoid the overhead of vtables, and because with less indirection, the compiler is better able to inline), better type safety (because the exact type is known, rather than hiding it behind an interface), and often cleaner and more concise code as well (STL iterators and algorithms enable much of this, without using a single instance of runtime polymorphism or virtual functions.

OOP is little more than an aging buzzword. A methodology that everyone misunderstood (The version supported by C++ and Java has little to do with what OOP originally meant, as in SmallTalk), and then pretended was the holy grail. There are aspects to it that are useful, certainly, but it is often not the best approach for designing an application.

Rather, express the overall logic by other means, for example generic programming, and when you need a class to encapsulate some simple concept, by all means design it according to OOP principles.

OOP is just a tool among many. The goal is not to write OOP code, but to write good code. Sometimes, the way to do this is by using OOP principles, but often, you can get better code using generic programmming principles, or functional programming.

jalf
A: 

The question is tricky because OOP encompasses several concepts: object encapsulation, polymorphism, inheritance, etc. It's easy to take those ideas too far. Here's a concrete example:

When C++ first caught on, zillions of string classes sprung into being. Everything you could possibly imagine doing to a string (upcasing, downcasing, trimming, tokenizing, parsing, etc.) was a member function of some string class.

Notice, though, that std::strings from the STL don't have all these methods. STL is object-oriented--the state and implementation details of a string object are well encapsulated, only a small, orthogonal interface is exposed to the world. All the crazy manipulations that people used to include as member functions are now delegated to non-member functions.

This is powerful, because these functions can now work on any string class that exposes the same interface. If you use STL strings for most things and a specialty version tuned to your program's idiosyncracies, you don't have to duplicate member functions. You just have to implement the basic string interface and then you can re-use all those crazy manipulations.

Some people call this hybrid approach generic programming. It's still object-oriented programming, but it moves away from the "everything is a member-function" mentality that a lot of people associate with OOP.

Adrian McCarthy