Reference variables in C++ - c++

Why are reference variables not present/used in C?
Why are they designed for C++?

Because C was invented first. I don't know if they hadn't thought about references at the time (being mostly unnecessary), or if there was some particular reason not to include them (perhaps compiler complexity). They're certainly much more useful for object-oriented and generic constructs than the procedural style of C.

Reference arguments were originally invented, AFAIK, for one thing: operator overloading semantics. For example, operator[] just must return a reference.
It was then a subject of great debate whether the 'concealed pointer' should be used for anything else ever.
Many development convention documents of many firms said "never use references. If you need a pointer, say so".
However, it was then discovered that references have one major advantage (no, not the syntax sugar). It is this: a reference is guaranteed to be valid, unless you work really hard to break it.
Personally, I still don't understand why I cannot do this in C++:
int a1, a2;
int &b = a1;
&b = a2; // Error. address of referenced is not an lvalue. Why?!

They're not present in C because they're not required. C has very few 'extraneous' features. You can write any program without using references, so they're just not included. C++ was developed much later than C was, so its designers threw in all kinds of stuff that wasn't originally present in C.

As you may know, C predates C++ by approximately a decade. References were a feature introduced in the C++ language. Some features of the C++ language have been adopted by subsequent versions of the C standard (such as const and // comment). The concept of references has not been so far.
One can hypothesize that their usefulness in object oriented programming does not translate as usefully to the procedural programming of C.

I think I agree with Pavel's idea that they were invented to make overloaded operators work properly. It's pretty clear that the first versions of C++ (C with classes) did not have references as if they did, this would be a reference instead of a pointer.

I guess C was born with a minimalist hat, and references are just syntactic sugar for pointers.

Related

Is C++ considered weakly typed? Why?

I've always considered C++ to be one of the most strongly typed languages out there.
So I was quite shocked to see Table 3 of this paper state that C++ is weakly typed.
Apparently,
C and C++ are considered weakly typed since, due to type-casting, one can interpret a field of a structure that was an integer as a pointer.
Is the existence of type casting all that matters? Does the explicit-ness of such casts not matter?
More generally, is it really generally accepted that C++ is weakly typed? Why?
That paper first claims:
In contrast, a language is weakly-typed if type-confusion can occur silently (undetected), and eventually cause errors that are difficult to localize.
And then claims:
Also, C and C++ are considered weakly typed since, due to type-casting, one can interpret a field of a structure that was an integer as a pointer.
This seems like a contradiction to me. In C and C++, the type-confusion that can occur as a result of casts will not occur silently -- there's a cast! This does not demonstrate that either of those languages is weakly-typed, at least not by the definition in that paper.
That said, by the definition in the paper, C and C++ may still be considered weakly-typed. There are, as noted in the comments on the question already, cases where the language supports implicit type conversions. Many types can be implicitly converted to bool, a literal zero of type int can be silently converted to any pointer type, there are conversions between integers of varying sizes, etc, so this seems like a good reason to consider C and C++ weakly-typed for the purposes of the paper.
For C (but not C++), there are also more dangerous implicit conversions that are worth mentioning:
int main() {
int i = 0;
void *v = &i;
char *c = v;
return *c;
}
For the purposes of the paper, that must definitely be considered weakly-typed. The reinterpretation of bits happens silently, and can be made far worse by modifying it to use completely unrelated types, which has silent undefined behaviour that typically has the same effect as reinterpreting bits, but blows up in mysterious yet sometimes amusing ways when optimisations are enabled.
In general, though, I think there isn't a fixed definition of "strongly-typed" and "weakly-typed". There are various grades, a language that is strongly-typed compared to assembly may be weakly-typed compared to Pascal. To determine whether C or C++ is weakly-typed, you first have to ask what you want weakly-typed to mean.
"weakly typed" is a quite subjective term. I prefer the terms "strictly typed" and "statically typed" vs. "loosely typed" and "dynamically typed", because they are more objective and more precise words.
From what I can tell, people generally use "weakly typed" as a diminutive-pejorative term which means "I don't like the notion of types in this language". It's sort of an argumentum ad hominem (or rather, argumentum ad linguam) for those who can't bring up professional or technical arguments against a particular language.
The term "strictly typed" also has slightly different interpretations; the generally accepted meaning, in my experience, is "the compiler generates errors if types don't match up". Another interpretation is that "there are no or few implicit conversions". Based on this, C++ can actually be considered a strictly typed language, and most often it is considered as such. I would say that the general consensus on C++ is that it is a strictly typed language.
Of course we could try a more nuanced approach to the question and say that parts of the language are strictly typed (this is the majority of the cases), other parts are loosely typed (a few implicit conversions, e. g. arithmetic conversions and the four types of explicit conversion).
Furthermore, there are some programmers, especially beginners who are not familiar with more than a few languages, who don't intend to or can't make the distinction between "strict" and "static", "loose" and "dynamic", and conflate the two - otherwise orthogonal - concepts based on their limited experience (usually the correlation of dynamism and loose typing in popular scripting languages, for example).
In reality, parts of C++ (virtual calls) impose the requirement that the type system be partially dynamic, but other things in the standard require that it be strict. Again, this is not a problem, since these are orthogonal concepts.
To sum up: probably no language fits completely, perfectly into one category or another, but we can say which particular property of a given language dominates. In C++, strictness definitely does dominate.
In contrast, a language is weakly-typed if type-confusion can occur silently (undetected), and eventually cause errors that are difficult to localize.
Well, that can happen in C++, for example:
#define _USE_MATH_DEFINES
#include <iostream>
#include <cmath>
#include <limits>
void f(char n) { std::cout << "f(char)\n"; }
void f(int n) { std::cout << "f(int)\n"; }
void g(int n) { std::cout << "f(int)\n"; }
int main()
{
float fl = M_PI; // silent conversion to float may lose precision
f(8 + '0'); // potentially unintended treatment as int
unsigned n = std::numeric_limits<unsigned>::max();
g(n); // potentially unintended treatment as int
}
Also, C and C++ are considered weakly typed since, due to type-casting, one can interpret a field of a structure that was an integer as a pointer.
Ummmm... not via any implicit conversion, so that's a silly argument. C++ allows explicit casting between types, but that's hardly "weak" - it doesn't happen accidentally/silently as required by the site's own definition above.
Is the existence of type casting all that matters? Does the explicit-ness of such casts not matter?
Explicitness is a crucial consideration IMHO. Letting a programmer override the compiler's knowledge of types is one of the "power" features of C++, not some weakness. It's not prone to accidental use.
More generally, is it really generally accepted that C++ is weakly typed? Why?
No - I don't think it is accepted. C++ is reasonably strongly typed, and the ways in which it has been lenient that have historically caused trouble have been pruned back, such as implicit casts from void* to other pointer types, and finer grained control with explicit casting operators and constructors.
Well, since the creator of C++, Bjarne Stroustrup, says in The C++ Programming Language (4th edition) that the language is strongly typed, I would take his word for it:
C++ programming is based on strong static type checking, and most techniques aim at achieving a high level of abstraction and a direct representation of the programmer’s ideas. This can usually be done without compromising run-time and space efficiency compared to lower-level techniques. To gain the benefits of C++, programmers coming to it from a different language must
learn and internalize idiomatic C++ programming style and technique. The same applies to programmers used to earlier and less expressive versions of C++.
In this video lecture from 1994 he also states that the weak type system of C really bothered him, and that's why he made C++ strongly typed: The Design of C++ , lecture by Bjarne Stroustrup
In General:
There is a confusion around the subject. Some terms differ from book to book (not considering the internet here), and some may have changed over the years.
Below is what I've understood from the book "Engineering a Compiler" (2nd Edition).
1. Untyped Languages
Languages that have no types at all, like for example in assembly.
2. Weakly Typed Languages:
Languages that have poor type system.
The definition here is intentionally ambiguous.
3. Strongly Typed Languages:
Languages where each expression have unambiguous type. PL can further categorised to:
A. Statically Typed: when every expression is assigned a type at compile time.
B. Dynamically Typed: when some expressions can only be typed at runtime.
What is C++ then?
Well, it's strongly typed for sure. And mostly it is statically typed.
But as some expressions can only be typed at runtime, I guess it falls under the 3.B category.
PS1: A note from the book:
A strongly typed language, that can be statically checkable, might be implemented (for some reason) just with runtime checking.
PS2: Third Edition was recently released
I don't own it, so I don't know if anything had changed on this regard.
But in general, the "Semantic Analysis" Chapter had changed both title and order in Table of Contents.
Let me give you a simple example:
if ( a + b )
C/C+= allows an implicit conversion from float to int to Boolean.
A strongly-typed language would not allow such an implicit conversion.

Why isn't std::initializer_list a language built-in?

Why isn't std::initializer_list a core-language built-in?
It seems to me that it's quite an important feature of C++11 and yet it doesn't have its own reserved keyword (or something alike).
Instead, initializer_list it's just a template class from the standard library that has a special, implicit mapping from the new braced-init-list {...} syntax that's handled by the compiler.
At first thought, this solution is quite hacky.
Is this the way new additions to the C++ language will be now implemented: by implicit roles of some template classes and not by the core language?
Please consider these examples:
widget<int> w = {1,2,3}; //this is how we want to use a class
why was a new class chosen:
widget( std::initializer_list<T> init )
instead of using something similar to any of these ideas:
widget( T[] init, int length ) // (1)
widget( T... init ) // (2)
widget( std::vector<T> init ) // (3)
a classic array, you could probably add const here and there
three dots already exist in the language (var-args, now variadic templates), why not re-use the syntax (and make it feel built-in)
just an existing container, could add const and &
All of them are already a part of the language. I only wrote my 3 first ideas, I am sure that there are many other approaches.
There were already examples of "core" language features that returned types defined in the std namespace. typeid returns std::type_info and (stretching a point perhaps) sizeof returns std::size_t.
In the former case, you already need to include a standard header in order to use this so-called "core language" feature.
Now, for initializer lists it happens that no keyword is needed to generate the object, the syntax is context-sensitive curly braces. Aside from that it's the same as type_info. Personally I don't think the absence of a keyword makes it "more hacky". Slightly more surprising, perhaps, but remember that the objective was to allow the same braced-initializer syntax that was already allowed for aggregates.
So yes, you can probably expect more of this design principle in future:
if more occasions arise where it is possible to introduce new features without new keywords then the committee will take them.
if new features require complex types, then those types will be placed in std rather than as builtins.
Hence:
if a new feature requires a complex type and can be introduced without new keywords then you'll get what you have here, which is "core language" syntax with no new keywords and that uses library types from std.
What it comes down to, I think, is that there is no absolute division in C++ between the "core language" and the standard libraries. They're different chapters in the standard but each references the other, and it has always been so.
There is another approach in C++11, which is that lambdas introduce objects that have anonymous types generated by the compiler. Because they have no names they aren't in a namespace at all, certainly not in std. That's not a suitable approach for initializer lists, though, because you use the type name when you write the constructor that accepts one.
The C++ Standard Committee seems to prefer not to add new keywords, probably because that increases the risk of breaking existing code (legacy code could use that keyword as the name of a variable, a class, or whatever else).
Moreover, it seems to me that defining std::initializer_list as a templated container is quite an elegant choice: if it was a keyword, how would you access its underlying type? How would you iterate through it? You would need a bunch of new operators as well, and that would just force you to remember more names and more keywords to do the same things you can do with standard containers.
Treating an std::initializer_list as any other container gives you the opportunity of writing generic code that works with any of those things.
UPDATE:
Then why introduce a new type, instead of using some combination of existing? (from the comments)
To begin with, all others containers have methods for adding, removing, and emplacing elements, which are not desirable for a compiler-generated collection. The only exception is std::array<>, which wraps a fixed-size C-style array and would therefore remain the only reasonable candidate.
However, as Nicol Bolas correctly points out in the comments, another, fundamental difference between std::initializer_list and all other standard containers (including std::array<>) is that the latter ones have value semantics, while std::initializer_list has reference semantics. Copying an std::initializer_list, for instance, won't cause a copy of the elements it contains.
Moreover (once again, courtesy of Nicol Bolas), having a special container for brace-initialization lists allows overloading on the way the user is performing initialization.
This is nothing new. For example, for (i : some_container) relies on existence of specific methods or standalone functions in some_container class. C# even relies even more on its .NET libraries. Actually, I think, that this is quite an elegant solution, because you can make your classes compatible with some language structures without complicating language specification.
This is indeed nothing new and how many have pointed out, this practice was there in C++ and is there, say, in C#.
Andrei Alexandrescu has mentioned a good point about this though: You may think of it as a part of imaginary "core" namespace, then it'll make more sense.
So, it's actually something like: core::initializer_list, core::size_t, core::begin(), core::end() and so on. This is just an unfortunate coincidence that std namespace has some core language constructs inside it.
Not only can it work completely in the standard library. Inclusion into the standard library does not mean that the compiler can not play clever tricks.
While it may not be able to in all cases, it may very well say: this type is well known, or a simple type, lets ignore the initializer_list and just have a memory image of what the initialized value should be.
In other words int i {5}; can be equivalent to int i(5); or int i=5; or even intwrapper iw {5}; Where intwrapper is a simple wrapper class over an int with a trivial constructor taking an initializer_list
It's not part of the core language because it can be implemented entirely in the library, just line operator new and operator delete. What advantage would there be in making compilers more complicated to build it in?

What are the bad habits of C programmers starting to write C++? [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 12 years ago.
A discussion recently ended laughing at the bad habits of programmers that have been too exposed to a language when they start programming in another language. The best example would be a Pascal programmer starting to #define begin { and #define end } when starting to write C.
Goal is to try to catch the bad habits of C programmers when they start using C++.
Tell about the big don't that you encountered. One suggestion by answer, please, to try to achieve a kind of best of.
For the ones interested in good habits, have a look at the accepted answer to this question.
Using raw pointers and resources instead of RAII objects.
using char* instead of std::string
using arrays instead of std::vector (or other containers)
not using other STL algorithms or libraries like boost where appropriate
abusing the preprocessor where constants, typedefs or templates would have been better
writing SESE-style (single-entry single exit) code
Declaring all the variables at the top of a function instead of as close as possible to where they are used.
Not using the STL, especially std::string,
and/or
using std::strings and reverting to old c string functions in tight corners.
Writing class definitions that are 2000 lines of code.
Copying and pasting that class definition into 12 different places.
Using switch statements when a simple virtual method would do.
Failing to allocate memory in constructor and deallocate in destructor.
Virtual methods that take optional arguments.
Writing while loops to manipulate char* strings.
Writing giant macro's that are a page in length. (Could have used templates instead).
Adding using's into header files so they can avoid names like std::string in type declarations.
using pointers instead of references
Very experienced developers not understanding casting or even object oriented programming:
I started helping out on a project and one of the senior guys was having a problem with some code that used to work and now didn't.
(Class names have been changed to protect the innocent, and I can't remember the exact names)
He had some C++ code that was listening to incoming message classes and reading them. The way it had worked in the past was that a Message class was passed in and he would interogate a variable on it to find out what type of message it was. He would then C-style cast the Message as another specialised class he'd written that inherited from Message. This new class had functions on it that extracted the data how he wanted it. Now, this had been working for him fine but now was not.
After many hours looking through his code he could not see a problem and I had a look over his shoulder. Immediately I told him that it's not a good idea to C-style cast Message to a derived class which it was not. He disagreed with me and said he'd been doing it for years and if that was wrong then everything he does is wrong because he frequently uses this approach. He was further backed up by a contractor who told me I was wrong. They both argued that this always works and the code hasn't changed so it's not this approach but something else that has broken his code.
I looked a bit further and found the difference. The latest version of the Message class had a virtual function and hadn't previously had any use of virtual. I told the pair of them that there was now a virtual table and functions were being looked up, etc, etc.... and this was causing their problem, etc, etc.... They eventually agreed and I was presented with a comment that I will never forget: "Virtual completely screws up polymorphism and object oriented programming".
I forwarded them a copy of a decorator pattern as an example of how to add a function to an existing class but heard nothing back from them. How they fixed the idea I have no idea.
One word: macros. I am not saying macros have no place at all in C++, but former C programmers tend to use them way too much after they switch to C++.
Using C-style casts.
C++ allows you to independently choose whether to allow casts between unrelated types, and whether to allow changes to const and volatile qualifiers, giving considerable improvements to compile-time type safety compared with C. It also offers completely safe casts at the cost of a runtime check.
C-style casts, unchecked conversions between just about any types, allow whole classes of error that could be easily identified by more restrictive casts. Their syntax also makes them very difficult to search for, if you want to audit buggy code for dubious conversions.
Assuming said programmers have already made the mistake of attempting to learn C++:
Mistakes
Not using STL.
Trying to wrap everything in classes.
Trying to use templates for everything.
Not using Boost. (I know Boost can be a real PITA, and a learning curve, but C++ is just C+ without it. Boost gives C++ some batteries).
Not using smart pointers.
Not using RAII.
Overusing exceptions.
Controversial
Moving to C++. Don't do it.
Try to convert C stdio to iostreams. Iostreams SUX. Don't use it. It's inherently broken. Look here.
Using the following parts of the libstdc++ library:
strings (beyond freeing them for me, go the hell away)
localization (what the hell does this have to do with c++, worse yet, it's awful)
input/output (64 bit file offsets? heard of them?)
Naively believing you can still debug on the command line. Don't use C++ extensively without a code crane (IDE).
Following C++ blogs. C++ blogs carp on about what essentially boils down to metadata and sugar. Beyond a good FAQ, and experience, I've yet to see a useful C++ blog. (Note that's a challenge: I'd love to read a good C++ blog.)
Writing using namespace std because everyone does and then never reflecting on its meaning.
Or knowing what it means but saying "std::cout << "Hello World" << std::endl; looks ugly".
Passing objects with pointers instead of references. Yes, there are still times when you need pointers in C++, but references are safer, so you should use them when you can.
Making everything in a class public. So, data members that should be private aren't.
Not fully understanding the semantics of pointers and references and when to use one or the other. Related to pointers is also the issue of not managing dynamic allocated memory correctly or failing at using "smarter" constructs for that(e.g. smart pointers).
My favourite is the C programmer who writes a single method with multiple, optional, arguments.
Basically, the function would do different things depending on the values and/or nullability of the arguments.
Not using templates when creating algorithms and data structures (example). It makes things either too localized or too generic
I.e. writing
void qsort(MyStruct *begin, size_t length); //too localized
void qsort(void *begin, size_t length,
size_t rec_size, int(compare*)(void*,void*)); //too generic
instead of
template <class RA_Iter>
void qsort(RA_Iter begin, size_t length);
//uses RA_Iter::value_type::operator< for comparison
Well, bad program design transcends languages ( casts, ignoring warnings, unnecessary precompiler magic, unnecessary bit-twiddling, not using the char classification macros ) , and The C language itself doesn't create too many "bad habits" ( Ok, Macros, esp from the stone ages ), and many of the idioms translate directly. But a few that could be considered:
Using a feature just because it's in C++ and so therefore it must be the right way to do something. Some programs just don't need Inheritance, MI, exceptions, RTTI, templates ( great as they are ... the debugging load is steep ), or Virtual class stuff.
Sticking with some code snippet from C, without thinking if C++ has a better way. ( There's a reason you now have class, private, public, const (expanded beyond C89) , static class funcs, references.
Not being familiar with the C++ i/o lib ( its BIG, and you do need to know it) , and mixing C++ i/o and C i/o.
He thinks that C++ is just a little more different language from C. He will continue programming C masked by C++. No advanced use of classes, the structs are considered less powerful than classes, namespace, new headers, templates, nothing of these new elements are used. He will continue declaring integer vars without int, he will not provide functions prototypes. He will use malloc and free, unsafe pointers and preprocessor to define inline functions. This is just a small list ;)
Confused uses of structs vs. classes, overuse of global methods that take object pointers as arguments, and globally-accessible instance pointers, a la:
extern Application* g_pApp;
void RunApplication(Application* app, int flags);
Also (not saying it's totally useless, but still):
const void* buf;
Declaring all the variables at the start of the function itself even if the variable will be used only after 100 lines or so.
Happens especially for local variables declared inside a function.
Solving the problem instead of creating a class-based monstrosity guaranteed to keep you in health insurance and 401K benefits.
Implementing lisp in a single file and doing the design in that.
Writing normal readable functions instead of overriding operators?
Writing in a style which can be understood by the junior programmers which see good practice as "not writing in C++".
Talking to the OS in it's own language.
Not leaving well enough alone, and using C instead.

What kind of polymorphism is considered more idiomatic in C++? [closed]

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 12 years ago.
C++ being a value oriented language doesn't seem to support OO (and thus sub-typing polymorphism) very well. As for parametric polymorphism, lack of type inference on type parameters and verbose syntax of templates makes them challenging to use.
Please note that the only languages I know moderately well are Java (sub-typing polymorphism) and Haskell (parametric polymorphism). Both languages are leaned towards one kind of polymorphism. However C++ supports both (to some extent), but both seem to work in a matter that I find unintuitive. So when programming in C++ I have a pretty hard time in deciding what way I should exactly code.
So my question is what kind of polymorphism is considered more idiomatic in C++?
EDIT 1:
Explanation of my "C++ doesn't support OO well" point:
Dynamic method dispatch and LSP are very common in OO, aren't they? But when it comes to C++, applying these techniques without resorting to pointers (raw or smart) is not possible (or practical).
For example,consider a class Person with virtual method print which prints his name to the console. Let there be another class Student that extends Person and overrides print to print his name plus his school's name.
Now consider the following function:
void blah(const Person & p) {
p.print();
}
Here if I pass a Student object, print method would invoke print from Person, not from Student. Thus it defies the very basic idea of subtyping polymorphism.
Now I am aware that I can use dynamic allocation (i.e. pointers) to achieve subtyping polymorphism in this case. However static allocation is more common in C++. Pointers are used as last resort (I remember having read it in some other thread here).So I find it difficult it difficult to reconcile the Good Practices that recommend static allocation over dynamic allocation (this is what I meant when I said C++ is value oriented) with subtyping polymorphism.
When using Java, I tend to use dynamic allocation all over and thus subtyping polymorphism is quite natural there. This is not the case with C++ however,
Hope my point is clear now.
EDIT 2:
Okay, the example I gave in my edit 1 is wrong. But my point is still valid and I have faced the problem many times. I am unable to recall all those cases top of my head.
Here's one case that comes to my mind.
In Java you can have reference of super type in your classes and then make them point to instances of any of its subtypes.
For example,
class A {
B y1;
B y2;
}
abstract class B {
// yada yada
}
class B1 exyends B {
// yada yada
}
class B2 extends B {
// yada yada
}
Here the references y1 and y2 in A can be made to point to instances of either B1, B2 or any other subclass of B. C++ references cannot be reassigned. So I will have to use pointers here. So this provs that in C++ it's not possible to achieve all sorts of subtyping polymorphism without using pointers.
Having added the fifth vote to reopen gives me a chance at being the first to add another reply. Let's start with the claim that C++ doesn't support OO well. The example given is:
Now consider the following function:
void blah(const Person & p) {
p.print();
}
Here if I pass a Student object, print method would invoke print from Person, not from
Student. Thus it defies the very basic idea of subtyping polymorphism.
To make a long story short, this example is just plain wrong -- or more accurately, the claim made about the example is wrong. If you pass a Student object to this function, what will be invoked will be Student::print, not Person::print as claimed above. Thus, C++ implements polymorphism exactly as the OP apparently wishes.
The only part of this that isn't idiomatic C++ is that you normally use operator<< to print out objects, so instead of print (apparently) printing only to std::cout, you should probably have it take a parameter, and instead of blah, overload operator<<, something like:
std::ostream &operator<<(std::ostream &os, Person const &p) {
return p.print(os);
}
Now, it is possible to create a blah that would act as described, but to do so you'd have to have it take its parameter by value:
void blah(Person p) {
p.print();
}
So there is some degree of truth to the original claim -- specifically, when/if you want to use polymorphism, you do need to use pointers or references.
Note, however, that this isn't related (any more than peripherally) to how you allocate objects. You can pass by reference regardless of how the object in question was allocated. If a function takes a pointer, you can pass the address of an automatically or statically allocated object. If it takes a reference, you can pass a dynamically allocated object.
As far as type inference goes, C++ has it for function templates, but not class templates. C++0x adds decltype and a new meaning for auto (which has been a reserved word, but essentially never used almost since the dawn of C) that allow type inference for a wider variety of situations. It also adds lambdas (the lack of which really is a serious problem with the current C++), which can use auto. There are still situations where type inference isn't supported, but would be nice -- but at least IMO, auto (in particular) reduces that quite a bit.
As far as verbosity goes, there's little question that it's at least partly true. Somewhat like Java, your degree of comfort in writing C++ tends to depend to at least some degree on an editor that includes various "tricks" (e.g., code completion) to help reduce the amount you type. Haskell excels in this respect -- Haskell lets you accomplish more per character typed than almost any other language around (APL being one of the few obvious exceptions). At the same time, it's worth noting that "generics" (in either Java or C#) are about as verbose, but much less versatile than C++ templates. In terms of verbosity, C++ stands somewhere between Haskell at (or close to) one extreme, and Java and C# at (or, again, close to) the opposite extreme.
Getting to the original question of which is used more often: there was a time when C++ didn't have templates, so essentially your only choice was subtyping. As you can probably guess, at that time it was used a lot, even when it wasn't really the best choice.
C++ has had templates for a long time now. Templates are now so common that they're essentially unavoidable. Just for example, IOStreams, which originally used only inheritance, now also use templates. The standard containers, iterators, and algorithms all use templates heavily (and eschew inheritance completely).
As such, older code (and new code from coders who are older or more conservative) tends to concentrate primarily or exclusively on subtyping. Newer and/or more liberally written code, tends to use templates more. At least in my experience, most reasonably recent code uses a mixture of both. Between the two, I'll normally use subtyping when I have to, but prefer templates when they can do the job.
Edit: demo code showing polymorphism:
#include <iostream>
class Person {
public:
virtual void print() const { std::cout << "Person::print()\n"; }
};
class Student : public Person {
public:
virtual void print() const { std::cout << "Student::print()\n"; }
};
void blah(const Person &p) {
p.print();
}
int main() {
Student s;
blah(s);
return 0;
}
result (cut and pasted from running code above on my computer, compiled with MS VC++):
Student::print()
So yes, it does polymorphism exactly as you'd want -- and note that in this example, the object in question is allocated on the stack, not using new.
Edit 2: (in response to edit of question):
It's true that you can't assign to a reference. That's orthogonal to questions of polymorphism though -- it doesn't matter (for example) whether what you want to assign is of the same or different type from what it was initialized with, you can't do an assignment either way.
At least to me, it would seem obvious that there must be some difference in capabilities between references and pointers, or there would have been no reason to add references to the language. If you want to assign them to refer to different objects, you need to user pointers, not references. Generally speaking, I'd use a reference when you can, and a pointer if you have to. At least IMO, a reference as a class member is usually highly suspect at best (e.g., it means you can't assign objects of that type). Bottom: if you want what a reference does, by all means use a reference -- but complaining because a reference isn't a pointer doesn't seem (at least to me) to make much sense.
Both options have their advantages. Java-style inheritance is far more common in real world C++ code. Since your code typically has to play well with others, I would focus on subtyping polymorphism first since that's what most people know well.
Also, you should consider whether polymorphism is really the right way to express the solution to your problems. Far too often people build elaborate inheritance trees when they aren't necessary.
Templates are evaluated at compile-time by creating basically a copy of the templated function or object. If you need polymorphism during runtime (ie: a std::vector<Base*> vec and vec->push_back(new Derived()) every now and then...) you're forced to use subtypes and virtual methods.
EDIT: I guess I should put forward the case where Templates are better. Templates are "open", in that a templated function or object will work with classes that you haven't made yet... so long as those classes fit your interface. For example, auto_ptr<> works with any class I can make, even though the standard library designers haven't thought of my classes really. Similarly, the templated algorithms such as reverse work on any class that supports dereferencing, and operator++.
When using subtyping, you have to write down the class hierarchy somewhere. That is, you need to say B extends A somewhere in your code... before you can use B like A. On the other hand, you DON'T have to say B implements Randomaccessiterator for it to work with templated code.
In the few situations where both satisfy your requirements, then use the one you're more comfortable with using. In my experience, this situation doesn't happen very often.
'Suck' is a pretty strong term. Perhaps we need to think about what Stroustrup was aiming for with C++
C++ was designed with certain pricniples in mind. Amongst others:
It had to be backwards compatible with C.
It shouldn't restrict the programmer from doing what they wanted to.
You shouldn't pay for things you don't use.
So, that first one makes a pretty stiff standard to stick to - everything that was legal in C had to work (and work with the same effect) when compiled in C++. Because of this, a lot of necessary compromises were included.
On the other hand, C++ also gives you a lot of power (or, as it has been described for C, 'enough rope to hang yourself.') With power comes responsibility, and the compiler won't argue with you if you choose to do something stupid.
I'll admit now, it's been about 15 years since I last looked at Haskell, so I'm a bit rusty on that - but parametric polymorphism (full type safety) can always be overridden in C++.
Subtyping polymorphism can to. Esentially, anything can be overridden - the compiler won't argue with you if you insist on casting one pointer type to another (no matter how insane.)
So, having got that out of the way, C++ does give lots of options with polymorphism.
The classic public inheritance models 'is-a' - sub-classing. It's very common.
Protected inheritance models 'is-implemented-in-terms-of' (inheriting implementation, but not interface)
Private inheritance models 'is-implemented-using' (containing the implementation)
The latter two are much less common. Aggregation (creating a class instance inside the class) is much more common, and often more flexible.
But C++ also supports multiple inheritance (true implementation and interface multiple inheritance), with all the inherent complexity and risks of repeated inheritance that brings (the dreaded diamond pattern) - and also ways of dealing with that.
(Scott Myers 'Effective C++' and 'More Effective C++' will help untangle the compexities if you're interested.)
I'm not convinced that C++ is a 'value oriented language' to the exclusion of other things. C++ can be what you want it to be, pretty much. You just need to know what it is you want, and how to make it do it.
It's not that C++ sucks, so much as C++ is very sharp, and you can easily cut yourself.

Features of C++ that can't be implemented in C?

I have read that C++ is super-set of C and provide a real-time implementation by creating objects. Also C++ is closed to real world as it is enriched with Object Oriented concepts.
What all concepts are there in C++ that can not be implemented in C?
Some say that we can not over write methods in C then how can we have different flavors of printf()?
For example printf("sachin"); will print sachin and printf("%d, %s",count ,name); will print 1,sachin assuming count is an integer whose value is 1 and name is a character array initililsed with "sachin".
Some say data abstraction is achieved in C++, so what about structures?
Some responders here argues that most things that can be produced with C++ code can also be produced with C with enough ambition. This is true in some parts, but some things are inherently impossible to achieve unless you modify the C compiler to deviate from the standard.
Fakeable:
Inheritance (pointer to parent-struct in the child-struct)
Polymorphism (Faking vtable by using a group of function pointers)
Data encapsulation (opaque sub structures with an implementation not exposed in public interface)
Impossible:
Templates (which might as well be called preprocessor step 2)
Function/method overloading by arguments (some try to emulate this with ellipses, but never really comes close)
RAII (Constructors and destructors are automatically invoked in C++, so your stack resources are safely handled within their scope)
Complex cast operators (in C you can cast almost anything)
Exceptions
Worth checking out:
GLib (a C library) has a rather elaborate OO emulation
I posted a question once about what people miss the most when using C instead of C++.
Clarification on RAII:
This concept is usually misinterpreted when it comes to its most important aspect - implicit resource management, i.e. the concept of guaranteeing (usually on language level) that resources are handled properly. Some believes that achieving RAII can be done by leaving this responsibility to the programmer (e.g. explicit destructor calls at goto labels), which unfortunately doesn't come close to providing the safety principles of RAII as a design concept.
A quote from a wikipedia article which clarifies this aspect of RAII:
"Resources therefore need to be tied to the lifespan of suitable objects. They are acquired during initialization, when there is no chance of them being used before they are available, and released with the destruction of the same objects, which is guaranteed to take place even in case of errors."
How about RAII and templates.
It is less about what features can't be implemented, and more about what features are directly supported in the language, and therefore allow clear and succinct expression of the design.
Sure you can implement, simulate, fake, or emulate most C++ features in C, but the resulting code will likely be less readable, or maintainable. Language support for OOP features allows code based on an Object Oriented Design to be expressed far more easily than the same design in a non-OOP language. If C were your language of choice, then often OOD may not be the best design methodology to use - or at least extensive use of advanced OOD idioms may not be advisable.
Of course if you have no design, then you are likely to end up with a mess in any language! ;)
Well, if you aren't going to implement a C++ compiler using C, there are thousands of things you can do with C++, but not with C. To name just a few:
C++ has classes. Classes have constructors and destructors which call code automatically when the object is initialized or descrtucted (going out of scope or with delete keyword).
Classes define an hierarchy. You can extend a class. (Inheritance)
C++ supports polymorphism. This means that you can define virtual methods. The compiler will choose which method to call based on the type of the object.
C++ supports Run Time Information.
You can use exceptions with C++.
Although you can emulate most of the above in C, you need to rely on conventions and do the work manually, whereas the C++ compiler does the job for you.
There is only one printf() in the C standard library. Other varieties are implemented by changing the name, for instance sprintf(), fprintf() and so on.
Structures can't hide implementation, there is no private data in C. Of course you can hide data by not showing what e.g. pointers point to, as is done for FILE * by the standard library. So there is data abstraction, but not as a direct feature of the struct construct.
Also, you can't overload operators in C, so a + b always means that some kind of addition is taking place. In C++, depending on the type of the objects involved, anything could happen.
Note that this implies (subtly) that + in C actually is overridden; int + int is not the same code as float + int for instance. But you can't do that kind of override yourself, it's something for the compiler only.
You can implement C++ fully in C... The original C++ compiler from AT+T was infact a preprocessor called CFront which just translated C++ code into C and compiled that.
This approach is still used today by comeau computing who produce one of the most C++ standards compliant compilers there is, eg. It supports all of C++ features.
namespace
All the rest is "easily" faked :)
printf is using a variable length arguments list, not an overloaded version of the function
C structures do not have constructors and are unable to inherit from other structures they are simply a convenient way to address grouped variables
C is not an OO langaueage and has none of the features of an OO language
having said that your are able to imitate C++ functionality with C code but, with C++ the compiler will do all the work for you in compile time
What all concepts are there in C++
that can not be implemented in C?
This is somewhat of an odd question, because really any concept that can be expressed in C++ can be expressed in C. Even functionality similar to C++ templates can be implemented in C using various horrifying macro tricks and other crimes against humanity.
The real difference comes down to 2 things: what the compiler will agree to enforce, and what syntactic conveniences the language offers.
Regarding compiler enforcement, in C++ the compiler will not allow you to directly access private data members from outside of a class or friends of the class. In C, the compiler won't enforce this; you'll have to rely on API documentation to separate "private" data from "publicly accessible" data.
And regarding syntactic convenience, C++ offers all sorts of conveniences not found in C, such as operator overloading, references, automated object initialization and destruction (in the form of constructors/destructors), exceptions and automated stack-unwinding, built-in support for polymorphism, etc.
So basically, any concept expressed in C++ can be expressed in C; it's simply a matter of how far the compiler will go to help you express a certain concept and how much syntactic convenience the compiler offers. Since C++ is a newer language, it comes with a lot more bells and whistles than you would find in C, thus making the expression of certain concepts easier.
One feature that isn't really OOP-related is default arguments, which can be a real keystroke-saver when used correctly.
Function overloading
I suppose there are so many things namespaces, templates that could not be implemented in C.
There shouldn't be too much such things, because early C++ compilers did produce C source code from C++ source code. Basically you can do everything in Assembler - but don't WANT to do this.
Quoting Joel, I'd say a powerful "feature" of C++ is operator overloading. That for me means having a language that will drive you insane unless you maintain your own code. For example,
i = j * 5;
… in C you know, at least, that j is
being multiplied by five and the
results stored in i.
But if you see that same snippet of
code in C++, you don’t know anything.
Nothing. The only way to know what’s
really happening in C++ is to find out
what types i and j are, something
which might be declared somewhere
altogether else. That’s because j
might be of a type that has operator*
overloaded and it does something
terribly witty when you try to
multiply it. And i might be of a type
that has operator= overloaded, and the
types might not be compatible so an
automatic type coercion function might
end up being called. And the only way
to find out is not only to check the
type of the variables, but to find the
code that implements that type, and
God help you if there’s inheritance
somewhere, because now you have to
traipse all the way up the class
hierarchy all by yourself trying to
find where that code really is, and if
there’s polymorphism somewhere, you’re
really in trouble because it’s not
enough to know what type i and j are
declared, you have to know what type
they are right now, which might
involve inspecting an arbitrary amount
of code and you can never really be
sure if you’ve looked everywhere
thanks to the halting problem (phew!).
When you see i=j*5 in C++ you are
really on your own, bubby, and that,
in my mind, reduces the ability to
detect possible problems just by
looking at code.
But again, this is a feature. (I know I will be modded down, but at the time of writing only a handful of posts talked about downsides of operator overloading)