Except OOP, why is C++ better than C? [closed]
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this questionWell that may sound like a troll question, but since C++ seems har开发者_如何转开发d to fully master (and I never really knew STL was actually "part" of it), I wanted to know what are the disadvantages to use C instead of C++ when not relying much on OOP.
C++ can have a very much sophisticated syntax sometimes, which is kinda confusing me while trying to use OGRE3D for example...
Non-OO features that C++ has that C does not:
- Templates
- Function overloading
- References
- Namespaces
- You can use
struct
s andenum
s without writingstruct
orenum
before every declaration or using typedefs. - Even if you don't define your own classes, using C++'s string and container classes is still often more convenient and safe to work with than c-style strings and arrays.
- Type safety (even though some would call it weak)
- Exceptions
- Variable declarations in conditionals, C99 only has it in
for
I'm a big fan of C
who over time has become a big fan of C++
. One of the big reasons for that is the STL ( the Standard Template Library ) and Boost.
Between the two of them it makes it very easy to write powerful portable applications.
Why C++ is better than C? Besides the obvious list of features, in my opinion the real answer is that there's no good reason to still use C instead of C++. Even if you don't use OOP, you can use it as a better C. Even if you use just once a unique feature of C++ in your program, C++ is already a winner.
On the other hand, there's no disadvantage in using C++: it retains the performance goals of C and it is a quite low level language, while allowing very powerful things. And you will not miss any C feature using C++!
And don't forget the wide user base and the rich libraries and frameworks available.
By the way, C99 has added some interesting features but after a decade there's still very limited compiler support (so you are bound to ANSI C). In the meantime C++ evolved as well and the compiler vendors are committed to providing conforming implementations.
One "feature" that hasn't been mentioned much (but I think is noteworthy) is that the C++ compiler community seems to be willing to go to a lot more work to produce conforming implementations. Back when the standard that eventually became C89/90 was in work, nearly every compiler vendor worked at conforming with the latest drafts of the standard, and (especially when the standard was close to complete) really put a lot of work into conforming as closely as they could.
That's no longer the case. The C99 standard was (obviously enough) completed over a decade ago, but there's still basically only one implementation that makes a serious attempt at conforming with the whole standard (Comeau). A few others (e.g., gcc) have added some C99 features, but are still missing a fair number of others. One (pcc) is in the rather paradoxical position of having added nearly all of the features specific to C99, but doesn't come very close to meeting the requirements of C89/90.
Given the complexity of C++, producing a conforming implementation is a much more difficult task. Despite this, I'd guess there are already more implementations that are at least really close to conforming with C++ 0x (due to be ratified a year or two from now) than with C99 (ratified roughly a decade ago). Just to pick an arbitrary number, I'd expect to see 3 conforming1 implementations of C++0x sooner than 3 conforming implementations of C99 (in fact, I'd almost expect that many the day it's ratified).
- Of course, "conforming" in this case means "to a practical degree" -- I'm pretty sure every implementation of C and C++ has at least a few defects that prevents perfect conformance. The same is true for most other languages, the only obvious exceptions being languages that are defined in terms of a particular implementation.
References are done automatically and much safer compared to pointers, the standard library is far more extensive, templates make code extremely customizable and substantially faster and safer. C++ offers fantastic code use/reuse and organization. Also, if you don't rely much on OOP, then you're doing it wrong. There's times when objects are not appropriate, but they're not the majority of scenarios.
One reason to write libraries in C is that it is very easy to use that library across languages since the C ABI is very simple, compared to the name-mangling mess that is C++ ABI. Creating C interfaces to the C++ libs might be a decent solution, but if you can express your API easily with C syntax, why write it in C++ to begin with?
Many C99 features are very nice, and are still not in C++.
[Note: this is a subjective response but the question itself tends to invoke subjective responses by nature].
C++ is a multi-paradigm language and there's a lot more to it than OOP. However, to suggest it's simply better than C is a bit... bold. :-D In the hands of an experienced C coder, and for the right purposes, C code can be very elegant and simple. Consider the Lua interpreter which is coded in C; it compiles to a very small binary which would have likely been a lot bigger even in the hands of an equally skilled C++ programmer, and is therefore well-suited for embedded use. C generally won't be as safe (ex: implicit casting, requires manual resource cleanup, etc) which is one thing which C++ strives to do a little better than C, but it also won't burden the programmer with awkward casting syntax (in C++ one shouldn't need to cast often, but in C it's quite common), e.g.
On the other hand, and I'm trying to speak very generally, C++ can actually make it easier to write more efficient code, particularly for code that needs to work across multiple types. The qsort vs std::sort benchmarks are a classic example of this and how C++, through templates and inlined function objects, can provide cost-free abstractions. In C one would have to write a separate sorting algorithm for every type by hand or stuff it in a macro to achieve comparable results.
Most C++ programmers who migrated from C never look back. I might be an oddball, but I still find C to be useful for implementing small scale libraries. For a start, it's a bit easier to port and builds super fast. For these kinds of things, I take implicit casting for granted. I would hate to work with any C code on a large scale, however, and have unfortunately have to do this from time to time.
As for specific differences, sepp2k already pointed out a pretty comprehensive list.
You can continue to write essentially C code but compile it as C++ and get the benefit of stronger type checking, and therefore more robust code.
You can then if you wish introduce the useful elements of C++ that have nothing to do with OO, such as a built-in bool
, function overloading, and better defined const handling (no need to use macros for literal constant symbols).
It is not even too much of a stretch to using some of the easier to understand and use elements of the standard library such as std::string
and iostreams, and even std::vector as a "better array"; you do not have to learn much C++ or understand OOP to take advantage of these improved interfaces.
Between OOP an procedural programming there is an intermediate Object Based Programming, which C++ supports and which is simpler to understand and learn and almost as useful as full OOP. Basically it uses abstract data types rather than full classes and eschews inheritance and polymorphism. To be honest it is what many C++ programmers write in any case.
Other than the upsides that sepp2k noted (and I aggree with) it certainly also has some little downsides that have not directly to do with OO. Come to mind the lack of __VA_ARGS__
for the preprocessor and the context sensitivity. Consider something like:
switch (argc) {
case 1: /* empty statement */;
toto T;
case 2: break;
}
In C, whenever the compiler encounters such a piece of code, and argc
and toto
are known, this is valid. (Sure we might get a warning for the unitialized T afterwards, whence we use it.)
In C++ this depends on the type toto
. If it is a POD, everything is fine (well, as fine as for C). If it has a constructor the code is not valid: jump to case label crosses initialization of 'toto T'.
So in some sense, for C++ you must understand the underlying types to see if a control flow is valid.
精彩评论