Many years ago I read a book from Prentice-Hall about object oriented programming. I don't remember exactly when that was - either shortly before starting studies at university or at the very start of the first year there. I read about methods and messages and I analyzed diagrams on which object A was said to be passing a message to object B by the means of calling one of B's methods.
Objects then seemed to me like active, almost living entities able to communicate through this mechanism of message passing (calling each other methods). I was disillusioned to learn later that this was not true. Objects didn't have concurrent lives and the so called message passing turned out to be ordinary, synchronous function call.
(The book contained examples in C++ and Smalltalk; I ignored Smalltalk examples while reading it; I realize now that my first impression of how objects communicate through message passing was, to great extent, true for Smalltalk).
That was the first bad thing I learned about C++.
Now after I've used several different languages based on different paradigms, I learned another bad thing about C++ (and so far that's the latest one): it is still being taught at universities and sometimes it is even the first or the only language being taught (I'm thinking here of studies in general, not necessarily computer science studies).
Is it the right choice to teach this particular language? Especially, if it is chosen just for an introduction to programming and, for some, the only language they will ever program in? In next short paragraphs I will try to persuade you that the answer is: no, it is not the right choice.
Lots of learning related to the language itself, not to programming in general
How constructors are called? In what sequence, when there is inheritance? Why do we have virtual destrutor and how it differs from regular destructor? When a class is abstract and when do we need one? What happens when some of the methods are virtual while some others are not? What results from weird combinations of access modifiers and/or mutliple inheritance?
The knowledge needed to answer all of these questions (and many others) does not allow anybody to actually write a useful piece of code. I agree this knowledge (or at least part of it) is needed to write a decent C++ program, I'm just saying it is not essential to write it, in the sense that there are other pieces of C++ knowledge that are essential, like flow control, and must be learned too in order to write anything useful. In languages like C or Python one only needs to learn the essential things to start programming, there is no or very little things related to the language itself that are necessary to write decent programs.
It takes away all joy
A student tasked with a problem to be solved by implementing an algorithm enjoys the task when he or she can jump instantly to doing a series of experiments, code one part, integrate it with another and run with different input data to test that it finally works.
With C++ it's difficult to do that: there is plenty of things one must care about, like memory management, that one must focus on, apart from focusing on the problem itself. This phenomenon is very clearly visible and can be experienced when one tries to solve a simple algorithmic problem in C++ and then Python or Lisp.
It creates false belief of what programming is about
For those who study something else than computer science using C++ for an introductory course creates an impression that a programmer must take care of a great number of small, complicated, yet very important things to achieve even an easy task (e.g. implement a queue in C++). Consequently, It makes it difficult to imagine that programmers are capable of creating much more advanced applications, web services and graphical interfaces. How do they do it, if even my simple queue implementation had several surprising deficiencies?
It is enough to read this fantastic article by Peter Norvig: http://norvig.com/spell-correct.html
to see that such an amazing thing as a spelling corrector can be written concisely and can be accessible and easy to comprehend to anyone who wishes to learn how it works. It wouldn't be as accessible (and would actually scare off many people), it were implemented in C++, or even in C, in this particular case.
Most of the criticism I expressed against teaching C++ is directed to doing a C++ course on studies other than computer science. It may be a valid course on CS studies, although I know that Carnegie Mellon University removed object oriented programming from CS introductory curriculum.
Many things that I listed could be said about teaching JAVA as the only language on non-CS studies, but JAVA is definitely less complicated both in terms of possible semantics (e.g. no multiple inheritance), has garbage collection and set of tools and libraries is immensly rich and easy to use.
C++ has lost its position that it had in late 90's. For all reasons listed above, I don't think it deserves to be taught such widely as it is today. I believe much more truth about programming can be conveyed with languages such as Python or even "old good" C.