可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
Recently, I finished reading K&R with its, almost all, exercises and examples. I was planning to move to "Accelerated C++" that I came across Axel Schreiner's book OOP with ANSI-C.
I am intrigued and want to learn it. But before investing time in it, I want to know the worth of implementing OOP in C. So that I can decide how much time I must spend on it.
- Implementing OOP in C, is it really used? Or its just for mental exercise?
- Are their any existing C projects that use OOP?
- When it is a good idea to use OOP in C?
- Should I invest my time in it?
I think its appropriate that I mention my background here so that you guys can guide me in a better way. I finished C, C++, Java and OOP theory about a year ago, have got a job too. But then Joel's blog and SO made me realize that I lack in a lot many things. So I picked up the books again and start studying them properly.
K&R, Accelerated C++, Algorithm in C++ and some other books are my attempt to to improve my skills. I am not new to OOP.
So what would you suggest?
Thanks for your time.
回答1:
OO is used in C as often as needed. Generally I don't agree with the opinion that one cannot do OOP in C, as soon as you provide set of functions that operate on a given type you have OOP. Take for example, you decide to create a data structure. If you provide functions to create, add, remove, and find elements of the data structure it's OO. Generally other languages provide syntactical sugar by automatically implying an instance variable and scoping in various properties of that instance automatically.
- As far as "is it really used", the answer is yes. It's not for mental exercise, it's a valid paradigm in C.
- The best example that comes to mind is GObject, used by GLib, GTK+ and many projects unrelated to GNOME. GObject provides a way of building objects in C. However it's not necessary to use third party support to have OO in C. Many existing projects have it, although it may not be present in the interface (a great thing in my opinion), and used internally for various purposes (cleanliness, data protection, all the usual OO justifications).
- It is a good idea to use OOP in C whenever you find the need to group behaviours and/or data. When you can justify the little extra syntactic expense in using your objects interface, and the time spent not actually completing your solution. Don't get sidetracked.
- You should not waste time learning OO because you think it's superior, rather it should complement your future solutions, and you should add it to your toolkit. Use it when it seems the right thing to do. Become familiar with how one does OO in C, the best way would be to do some C++, or examine any good project that uses a little C-style OO. It will seem natural to you after that.
回答2:
Implementing OOP in C, is it really used? Or its just for mental exercise?
Yes, it's really used, but unsurprisingly, it's not as common as OOP in languages that were designed for it.
Are their any existing C projects that use OOP?
I can remember using a couple:
- GLib GObject System
- GTK+ GUI framework
When it is a good idea to use OOP in C?
Some problems are very well modeled by OOP. GUIs, for example, are often designed with inheritance between window types, using polymorphism to override and specialize behavior.
You should use OOP whenever your problem has a beautiful OOP solution. With the footnote that you shouldn't stick 100 lines of OOP code in a 15000 line project, just because it's "kewl"! :)
Should I invest my time in it?
That really depends on what you plan to do with it. I'd never advocate not learning anything - it's great to get exposure to how, why and when to use it. It's great to see a language that wasn't designed for OOP support OOP. You read the book, so I assume you have some affinity to C and interest in OOP. Give it a shot, maybe throw together some GUI applications in GTK+. On the other hand, if you're looking to become the next design patterns master web developer, it's probably not the best approach, you may consider other languages that are more focused toward that area.
So what would you suggest?
I'd suggest you use the best tools at your disposal that fit the problems you're trying to solve. Decide what problem you're going to solve. A GUI desktop app, a web server, a game, a cmd line utility... once you decide on your problem, you'll be able to better decide which technology fits for developing a solution. I've found that you can't really master anything with "toys", so you need to be doing something real.
回答3:
I've had experience with several advanced C projects which make at least some use of OOP. The most well known is the Linux kernel.
The kernel is entirely C (except for platform specific pieces in assembly for hardware interfaces).
The kernel makes heavy use of structures with function pointers in many places. The first that comes to mind is file systems. Drivers fill in the file_operations struct (as well as many others) with callbacks to their specific implementations.
The kernel also makes a lot of use of goto
statements which in some contexts can be thought of as rudimentary throw statements leading a label at the end of the function to do some clean-up and exit. (Though they do also use goto
for a lot more than just error handling, and it is also only used for "exceptions" within a function, not for passing them outside.)
回答4:
There are people who say you can write object oriented code in any language, and there are also people who say you can write horribly unstructured code in any language.
Real "OO" language provide you with a handful of mechanisms for implementing OO design: The languages have built-in concepts for object and/or classes, for encapsulating code with data, for inheritance and so on. C has essentially none of this, but there's nothing stopping you from doing OO programming in C, given some techniques and self discipline (as your book surely tells you).
But would you want to?
My opinion is this: If you're just learning to do OO programming, it might make more sense to learn this while being "held by the hand" by a language which already deeply incorporates the concepts. A well-structured, simple and interactive language would be nice for this: Given a free choice, I'd recommend Ruby, Python or Groovy. Given a language with built-in OO "magic" it becomes very obvious when you're doing OO things and when you're just being structured, disciplined and well-organized. There may also be stuff to be learned when moving from C to another language: The commonalities, the differences.
Some people would recommend learning C++ as the natural OO progression from C. I don't wholeheartedly support this, because I consider C++ a rather ugly bolting-on of OO capabilities on a language that was already more "practical" than elegant. When moving from "standard" C programming to OO programming, I think a programmer should consider moving away from direct manipulation of pointers, for example, and certainly I'd find it burdensome to have to manage memory for my data. Modern OO languages automate this so that a programmer has more brain cells left over for higher-level tasks. The appeal of C++, of course, is raw speed. Because it can drop to the same near-metal level as C, it is usually the "fastest" of OO languages.
All that said: If you have a big project where the required language is C and you want to use and practice OO techniques, then by all means go ahead! If not, you might benefit from learning OO in an environment that encourages and supports this, and perhaps later coming back to C with your knowledge of OO. The techniques taught in the book will make sense to you then, and you'll be in a better position to decide if you really want to do this in C or in a "real" OO language.
回答5:
Maybe see the ooc-lang project mentioned here:
http://attractivechaos.wordpress.com/2009/09/20/oop-in-c-dont-go-too-far/
回答6:
It can be, but without the destruction-time function-calls provided by other OOP languages, it's not that useful. In addition, if you need OOP, there's always C++, where your code is virtually instantly portable to it.