The main difference I can think of is that C++ is far more of a multi-paradigm language than C and C#. In C#, OOP is still the paradigm. It's a OOP language before anything else, and if you're not doing OOP, the C# community will tell you you're doing it wrong.
(although C# has added quite good support for a few bits of functional programming as well, over the last few years).
In C++, OOP is, well, it's supported and you can use it when you feel like it, but all the fuss is around generic programming. C++ templates allow a wide range of clever, reusable and generic libraries, and achieve many of the same goals as old-fashioned OOP, but without the big inheritance hierarchies and with virtually no coupling between classes. The standard library contains many examples of this
In C++, a lot of C constructs, while still legal, are basically shunned:
- Raw pointers (usually replaced with smart pointers such as
boost::shared_ptr
or std::auto_ptr
, or with references
- Memory allocations in user code (Should usually be wrapped in smart pointer, or in a custom-made RAII object)
- Function pointers (Usually replaced with functors, for better type safety and performance)
- goto (Is often used in C to jump to cleanup code. Again, made unnecessary by RAII)
- the preprocessor (Is virtually never necessary. Prefer templates instead)
Of course, there are exceptions to every one of these points, but as a general rule of thumb, C++ code will, unlike C code, pretty much eliminate all use of these.
And more than in C#, classes are really workhorses doing a lot of the heavy lifting. In C#, a class is little more than a bit of scaffolding, a container to stick all your methods in. Sure, it has a constructor, and it may implement Dispose(); but C++ takes it a lot further, and you have:
- The constructor (just like in C#, which initializes the class from scratch)
- The copy constructor (initializes a class as a copy of another object)
- The assignment operator (Because classes are what C# would consider value-types. And so assignment is not just changing a reference, but copying over all the contents of the object, in a user-defined manner)
- The destructor
The destructor is probably the most important concept in C++. It is vital to RAII, which is how memory or other resources are managed, because it is automatically called when an object goes out of scope. That allows your classes to make a whole lot of guarantees that are impossible to achieve in C or C#.
For example, boost::thread provides a scoped locks which is guaranteed to be released when it goes out of scope, whether the function returns normally, an exception is thrown, or anything else. So when using this library, the user doesn't have to worry about releasing locks or other resources. It just happens automatically, as soon as you're done with them.
In a sense, this gives you a lot more hooks to customize the behavior of your class. Unlike in C#, you control exactly what happens when a simple assignment is executed. You control what happens when the class goes out of scope, when it is initialized from scratch or as a copy of another object. This allows a well-written class to be almost impossible to use incorrectly. (Almost)
Apart from this, templates and template metaprogramming are concepts you'll probably run into. They're extremely powerful tools, so make sure you're on friendly terms with them. :)