Even though OOP uses objects and data encapsulation, the code still writes out like a procedure. So what makes OOP loose the procedural label? Is it just because it is considered "high-level"?
Thank You.
It's not that Object-orient Programming is "non-Procedural"; it's just that the code we call "Procedural" is not Object-oriented (and not Functional and probably not a couple others)
It's not so much an either-or case, but a slow gradiate:
Spaghetti code -> Structured Code -> Object-oriented code -> Component code.
(UPDATE: Removed "Procedural" from the chart above, since it refers to all of the right 3/4rds of it)
In theory OOP and procedural programming are orthogonal concepts. The fact that they so intertwined in practice is probably more coincidence than anything else. Because it is so familiar, procedural syntax is the most human readable format around. Message-passing, functional computation expressions, and various other formats -- because of their unfamiliarity -- are simply not as easy for most programmers to work with. Couple this with the fact that most OOP systems are based on extensions to procedural languages, and it becomes pragmatically difficult to separate the two paradigms. (As a side note: That's one of the things I like about F#; as a multi-paradigm language, it helps conceptually separate the various aspects of OOP, imperative programming, functional programming, while making all of them available.)
I would say object-oriented and procedural are orthogonal concepts. Many popular object-oriented systems are extensions of procedural languages, but not all. For example, Dylan reads like a blend of functional and object-oriented programming.
This is just a 'convention' thing. When people say 'procedural', it is implied that it isn't OO, and vice-versa.
OOP does not loose procedural label. Procedural programming is imperative programming. OOP extends procedural programming. C++ and Objective C are OO extensions of C. Functional programming usually is declarative - opposite of imperative.
From Wiki (well explained):
The focus of procedural programming is
to break down a programming task into
a collection of variables, data
structures, and subroutines, whereas
in object-oriented programming it is
to break down a programming task into
objects with each "object"
encapsulating its own data and methods
(subroutines). The most important
distinction is whereas procedural
programming uses procedures to operate
on data structures, object-oriented
programming bundles the two together
so an "object" operates on its "own"
data structure.
More can be found here.
The Wikipedia article at http://en.wikipedia.org/wiki/Procedural_programming provides a decent explanation of the differences between object-oriented programming and procedural programming, but in short, object-oriented programming is about the exchange of messages between collaborating objects rather than stringing procedures together to operate upon loose data structures.
Internally, objects do resemble little procedural programs, but their data isn't publically exposed and operated upon by other objects. The "Tell, Don't Ask principle" is an object-oriented design principle that perscribes this interaction between objects. The study of this principle may help to shed further light on the nature and intent of object-oriented design over procedural design.
It never loses procedural label. Its a mis-conception. OOP is much more than encapsulation and objects. Click here for more info.
I think one of the distinctions is that virtual properties and methods are used much more heavily in object-oriented languages than are function pointers in languages like C. In C, if I say foo(x), it's pretty clear that I'm doing one of two things, and the declaration of foo(x) will tell me which one. I'm either calling a function named foo(), or I'm calling a function pointed to by a function pointer named foo(). In an object oriented language, when I write foo(x), that may get implicitly mapped to invoke code which didn't even exist when my module was compiled.
Depends on your definition of 'oriented'.
If 51% of the code is O-O, does it qualify?
OOP is not just encapsulation.
Polymorphism is one of its most powerful feature.
Related
Most of my understanding of how clojure handles immutables comes from this. This seems really clever to me; it makes things like copying and changing one value or adding a new value to the end of a collection nearly as quick as it would be for a mutable object. However, from what I understand many (if not most) other languages that rely heavily on immutables don't use this sort of structure (Haskell, Scala, etc.). Why is that? is there some disadvantage to such a tree structure that I'm missing, or just a relatively recent idea?
The short answer is your understanding is mistaken. The kind of data structure you are referring to is called persistent, and nearly all functional programming languages have made heavy use of them for at least a couple decades now, including Scala and Haskell.
Where they are still not heavily used is in primarily imperative languages that also do functional programming as an afterthought. That's why trying to "go immutable" in these languages is often much less efficient than in primarily functional languages.
I have always heard that C++ is not Object Oriented but rather "C with Classes". So, when I mentioned to an interviewer that C++ was not really object oriented, he asked me why I didn't consider it an OO language. I haven't done any C++ since University, and I didn't have much of an answer. Is C++ Object Oriented or not? and why?
C++ is usually considered a "multi-paradigm" language. That is, you can use it for object-oriented, procedural, and even functional programming.
Those who would deny that C++ is OO generally have beef with the fact that the primitive types are not objects themselves. By this standard, Java would also not be considered OO.
It is certainly true that C++ isn't OO to the same extent as Smalltalk, Ruby, Self, etc. are, but it is definitely an effective OO language by most standards.
C++ is a multi-paradigm programming language supporting
imperative
object-oriented (class-based)
generic (template metaprogramming)
programming styles. You can choose (and mix them) freely to meet the needs for your project.
C++ is an object oriented language. The problem is that some language zealots have their own, sometimes conflicting definition of OOP. For example, some Java people say that C++ is not an OOP language because you can define functions outside of a class.
Just ignore them.
Bah! The people who say C++ isn't object oriented are the same ones that would say Spam isn't food :-)
The OO "religious nutter" crowd will say that you can only have a true OO language if absolutely everything is an object. That's fine, they can sit in their ivory towers and believe what they want. Some of us have actual jobs to do.
Provided you use the object mindset, C++ (and even C if you use all sorts of tricks with function pointers within structures) is more than enough to be considered object oriented.
Meh. Everybody has their own deinition of OOP. Alan Kay who invented the term OOP said: http://www.noulakaz.net/weblog/2007/02/12/true-meaning-of-oop/
OOP to me means only messaging, local
retention and protection and hiding of
state-process, and extreme
late-binding of all things. It can be
done in Smalltalk and in LISP. There
are possibly other systems in which
this is possible, but I’m not aware of
them.
By that definition even Java, C#, Python etc are not OO languages.
IMHO, these discussions are pointless.
The hallmarks of object-orientation are abstraction, encapsulation, polymorphism, and inheritance.
I'd say that C++ exhibits all four, so it qualifies as an object-oriented language.
It's possible write C++ as "a better C" and use a purely procedural style. Objects aren't mandated. Maybe that's what you're thinking.
C++ is an OO language.
But that is not the only style of coding that C++ can be used in. n
As such C++ is technically a multiparadigm language of which OO is just one paradigm.
The term "C with classes" has a couple of meanings.
It can refer to the fact the C++ is OO (as classes give it the OO capabilities).
It can refer to the original version of "cfront"
Which was basically C with the extension of classes and little else.
It can refer (derogatorily) to a style of programming that does not utilize the full power of C++ but only uses a small subset of the language.
The idea is that C++ is not just an object oriented language.
C++ is object oriented, because classes provide abstraction and inheritance and all that jazz. It's not always considered object oriented because code doesn't need to be object oriented. It's like saying Scheme isn't functional because it has set!.
As other have said, C++ is not a PURE OO language. Then again, the only Pure OO language I know is smalltalk. The only pure functional language I know is the Lambda Calculus. I don't know ANY pure structured languages (They all have goto and/or multiple return statements)
Most people don't like writing in pure programming languages. It cramps their style.
The term "object oriented" is too hazy to give a definite yes or no answer. I think you'll find the majority view is that C++ is an OO language, or at least that you can write in an OO way in C++. If you want a more definite answer, you'll have to ask a better defined question, such as:
Q: Does C++ have "object" (i.e. data fields + associated member functions) data types?
A: Yes.
Q: Does C++ have non-object data types?
A: Yes.
Q: Does C++ have non-member functions?
A: Yes.
C++ is object oriented. c++ is c with classes is another way to say that c++ is c with oop added (and of course, there is more than that on top of c).
If I am an interviewer asking you this question, I'm probably not caring about the yes/no answer - I really want to know what you understand about programming, and C++ or other languages. Are you just throwing out terms that you don't think about or understand, or do you actually consider carefully what you are doing and saying. So in this situation a good answer is
"I define Object oriented coding to be a, b, c, and d. I define an Object Oriented language as one which supports that definition, ie. permits me to (easily / uniformly / rigorously / other adjective ) develop code that fulfills those requirements. C++ delivers a,b,c, and partially on d. So I do ( don't ) consider C++ to be OO for those reasons."
For my personal definition, C++ is object-oriented enough, plus it supports other approaches.
Stroustrup, who designed C with classes, viz. the original implementation of the ISO C++ standard, answered the same question in ACM's OOPSLA '95. The paper's softcopy is available at http://www.stroustrup.com/oopsla.pdf.
It is indeed object oriented but not strictly though.
Say for example, we can have just
int main()
{
return 1;
}
which is nothing in the name of Object oriented and on the other hand we can have Classes, inheritance, polymorphism etc., that corresponds to Object Oriented.
It is up to us unleash the power of the language.
To the interviewer who asked you the question show a class a from C++ and ask him whether it is structured or procedured.. He will show you the same main() function I guess :)
So I guess it is based on what you have implemented that lies. But it has features that can make it to be considered as an OOP.
C++ is not an object-orientated language. The language is not any paradigm. This is in constrast to Java, which is religiously object orientated (no friend statement, for example). C++ offers object orientation, but isn't inherently object-orientated.
C++ is partially OO because the code can be written without the class and it has also multiple inheritance concept, i.e one child can have more than one parent.
Object-oriented programming (OOP) has become the preferrd programming approach by the software industries, as it offers a powerfull way to cope up with the cpmlexity of real world probleams. Among the OOP languages available today, c++ is far the most widely used language.
The languages should support several of the OOP concepts to claim that they are object oriented. depending on the fetures they support , they can be classified in to two categories.
Object-Based programming languages.
Object-Oriented programming languages.
Object-Based programming languages.
if it supports
A. DATA ENCAPSULATION
B. DATA HIDING AND ACCESS MECHANISAMS
C. AUTOMATIC INITIALIZATION& CLEAR-UP OF OBJECTS
D. OPERATOR OVER LOADING
2.Object-Oriented programming languages.
It supports all object-based programming features along with two additional features
E. INHERITANCE
F. DYNAMIC BINDING
hence Object-Oriented programming languages means
**Object-based features+ inheritance+ dynamic binding.**
Examples : C++, SMALLTALK,OBJECT PASCAL,JAVA
So , C++ is an OBJECT-ORIENTED PROGRAMMING LANGUAGE>
If you should still have some doubts in object oriented programming concepts refer the book of E.Balaguruswamy.
Why isn't openGL object-orientied? Everybody teaches Object Orientated Programming + Design Patterns, but OpenGL has many global functions. Isn't this bad style?
The whole point of a low-level API is to make it as minimal and portable as possible. Giving it an object-oriented architecture would not allow this:
Polymorphism adds unnecessary function call overhead.
It forces you to use some relatively difficult calling convention, which reduces portability.
You cannot wrap an object-oriented architecture to make it procedural, but you can do the reverse; so, it makes sense to make things as flexible as possible. It's trivial to write an object-oriented wrapper around OpenGL if you want.
Finally, you should really question what you've been taught about OOP. Despite what your college or university may tell you, OOP is not a panacea of program design. There are very good reasons why there is absolutely no object-orientation in the C++ STL (and most of Boost for that matter).
Object-orientation is useful in some cases, but you should learn when it is useful, and when it is not, and under no circumstances should you believe that anything that is not OOP is "bad style".
OpenGL
OpenGL should support all platforms -- there's nothing near to C in this regard - thanks to that almost every device can use the same API
OpenGL should support all languages -- there's also nothing near to C in this regard - thanks to that, each language that supports calling C libraries (and almost all do) can use OpenGL
OpenGL is an API, not a engine -- it intends to provide low level interface to the graphics harware, yet enough high level, to be an abstraction to different hardwares -- C is a lot more low level than C++, OOP is not low level
OpenGL is a framework to build upon, not a complete solution -- there is no one and true way to write graphics code, and OpenGL isn't supposed to force us to anything - by being OOP it would force us to their "colution
OpenGL is not tied to any specific programming paradigm -- hence we can wrap OpenGL into a functional, logical or OOP language -- or use it procedurally
OpenGL is about efficiency -- and you can't get more efficient than by direct function calls. OOP is as efficient as it is suited for a particular task.
In general -- OpenGL is designed to allow us to have all the freedom, and don't make any choices for us. And by freedom I mean freedom to choose a platform, a language, a programming paradigm, a engine design, a methodology, and a level of efficiency vs. readability.
And for that I praise OpenGL, and for that I hate Direct X.
Amen.
Sidenote: Everybody teaches Object Orientated programming because it's the easiest to grasp. It's not the one and only true paradigm. There's functional programming, logical programming, contract programming, and even a object oriented way to write in C. There's no one truth in computer science. As for Design Patterns, I could name more than a few that are used in OpenGL's architecture. Bad Style? I've seen beautiful C programs that had aaaaallll global functions...
In general, OpenGL is object oriented. It is just implemented in a language that doesn't directly support OOP. But the API is object-oriented: It consists of a number of different object types, and a set of operations defined on each. And the internals of each object type are hidden from the user. It fulfills all the requirements for OOP. It just so happens to be implemented in C, which doesn't have a convenient class or member method syntax.
Apart from this, there is absolutely nothing wrong with global functions. In C++, a common recommendation is to prefer them over member methods whenever possible. In functional programmming, global functions are the default.
OpenGL was created for and in C, and none of that stuff existed then. Even now, they still want to keep a C interface, because C is still a widely used language.
Should they maintain both C interfaces and C++ wrappers, ditch C and just use C++, or keep a C interface? I'd argue the latter is the best solution: easy on them, not too hard for us.
That said, the OpenGL interface is admittedly gross. Lot's of stuff was "suppose" to be deprecated, but alas that got moved to a later date.
Well, there are a few reasons.
You should think of an OpenGL context as a state machine. There is only one of them active at any time. There is no difference between putting a little Opengl.whatever in front of everything.
Speed, OpenGL was designed to be a minimal API
If it was object oriented, what language would you write it in? C++? Then everybody would ahve to write complex bindings. C is WAY easier to wrap.
I know that in OOP we have to declare everything e.g. variables, functions, etc. inside a class like in Java, but in C++ we can declare outside the class too.
Is this the reason that, C++ is not fully OOP? Or is there anything else?
Huh? C++ is a hybrid, multi-paradigm language. It is certainly not a "pure" object-oriented language, where "everything is an object" holds true. C++ supports classes, objects, encapsulation, and so on, but since it's also (more or less) backwards-compatible with a lot of C code, it cannot be "fully object-oriented".
Object-Oriented Programming is not definition of the language, it's definition of the programming, a program. I.e. one program in C++ can be OOP, and other can be not OOP.
What you can say is that C++ fully supports means of programming in OOP paradigm.
Define fully OOP? There are as many opinions as people probably
Note as far as purity goes, IIRC all languages with valuetypes are not "pure" in the strict sense. No, boxing doesn't count.
Over the years, in discussion I've tried to go back to the core OOP features:
identity
Classification
polymorphism (not inheritance, since some OOP have no inheritance)
encapsulation
So if you can tell if two classes are not the same class (identity), you can make the classic "duck quacks" and "dog barks" example (to demonstrate inheritance/polymorphism and classification) and you can hide fields, you are pretty much there.
Applying it to all the languages is more difficult though. While I do get functional programming roughly, I'm not trained enough in the their near infinite jargon to judge all those functional-oop-imperative hybrids that are springing up,
In C++ you don't HAVE to code using OOP, you can choose not to use it. Having said that, it's "fully OOP", OOP is just just not a requirement.
not even java is a full OOP language.
in real OOP languages everything is an object, conditionals, loops, etc.
Even though the question is somewhat ugly phrased I'm not really satisfied with all the answers provdided yet.
I preffer to think of languages as "supporting a paradigm" and not "being in a paradigm".
So, when does a language support a paradigm? When it is easy to write code that satisifies the requirements of the paradigm.
How one comes to this conclusion? Consider the style linux filesystems are implemented. It is C-Code that clearly has OO properties. So, would you not consider this code to be OOP because C is not a OOP-language? I don't think so. (I guess some people will rightfully disagree as this seems to be amtter of opinion.)
What does this imply for C++? Well, C++ has a lot of facilities for making it easier to program in a OO-Style, but it also provides you with a lot of means to rape the paradigm and write code that looks OO (because you use classes, inheritance private variables) but completly violates some other OO-principles (e.g. single responsibility, open-closed, uniform access).
I would conclude that C++ supports the OO-paradigm to some extent but is clearly inferior to some of the modern OO languages.
The main concept of OOP is that every member in an object oriented programming language should be defined inside of the class, whereas in c++ the main function is defined outside of a class. That is why c++ is not fully object oriented programming language.
The main() function is not inside a class, so for this reason, one could argue that C++ is not fully OOP.
One of the reason C++ is not fully OOP is the requirement of backward compatibility with a lot of C code. Built in types are not Objects in C++ as it is less efficient if they were. Remember, C++ first target audience were existing C programmers and efficiency was (is) a great concern.
However, C++ supports all the important features of OOP.
Related Link : www.research.att.com/~bs/oopsla.pdf
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.
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.
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.
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.
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.
I suggest you read Bjarne's Paper about Why C++ is not just an Object-Oriented Programming Language
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.
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.
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.
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.
I'm used to be an OOP fanboy... Then realized using functions, generics and callbacks can often make a more elegant and change-friendly solution in C++ than classes and virtual functions.
Other big names realized it too: http://harmful.cat-v.org/software/OO_programming/
IMHO, I have a feeling that the OOP concept is not really suits the needs of the Big Data, as OOP assume all the stuff to be kept in memory (concept of Objects and member variables). This always result in memory demanding and heavy applications when OOP is used for example for big images processing. Instead, the simplicity of C maybe used with intensive parallel I/O making apps more efficient and easy to implement. It is the year 2019 I am writing this message...Everything may change in a year! :)
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.
I'd say the greatest benefit of C++ OOP is inheritance and polymorphism (Virtual function etc...) .
This allows for code reuse and extendibility
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...
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.
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.
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.