tags:

views:

419

answers:

14

Here's a simple question.

I've done plenty of work using both C & C# (2.0) but never anything in C++. What can I expect to be different when learning C++? Will there be any big gotcha's or hurdles I should pay attention too? Does anyone good crash course book/website recommendations for learning C++ for the experienced programmer?

A: 

The bigest "hurdle" will probably be that you'll be responsible for releasing the memory you allocate

Sean
he's coming from a C background, there is less memory management in C++, not more.
gbjbaanb
+2  A: 

Hmmm... Tough one. If you are ok with .NET and pointers, there shouldn't be too much new.

I think dealing with C++ header files will be an experience. There's also the C++ STL to familarise yourself with.

You might also have to deal with people shouting at you about things like Multiple Inheritance.

biozinc
A: 

As posted already you will probably be responsible for your memory management but other then just learning the C++ libraries and how to organize including them I think it should not be a tough switch at all.

Andrew Jahn
+4  A: 

I strongly suggest: "Effective C++ and More effective C++". And if you're at it, "Effective STL" might be of some help :)

Those books were written particularly for smart programmer who need to handle C++ effectivly. I attest that Effective C++ was the one that helped me the much when I have begun C++!

Another good book for C++ beginner (but I don't think computer beginner), is "Accelerated C++". It focuses primarely on good coding, stl, and producing high level code instead of focusing on the details. (those are covereled more in the end of the book).

good luck :)

+3  A: 

Well I've been using C++ for over 10 years now, so my answer would be, learning strict memory management, C++ templates, STL, then Boost. This should take you a few months, then the nitty gritty will take you say 5 years :)

As for books I like Herb Sutter's Exceptional C++ and More Exceptional C++

Robert Gould
Hmm... you learn something new every day. What memory management aspects are new in C++ as compared to plain C? I've been under the impression that the nasty stuff is in C already.
biozinc
Well to begin you use new/delete ,as opposed to malloc/free, next you have new/delete overloading, then you have instance allocators, class allocators, smart pointers galore, to name a few obvious ones
Robert Gould
Thanks! Now I know more things to look out for when I get back to C++.
biozinc
You're right, the nasty stuff is already in C. It's pretty misleading to tell a C programmer that "In C++ you have to learn memory management". C++ just adds various ways to wrap memory allocations.
jalf
+8  A: 

Here are some from my point of view:

  • Pointers play a big role in C++. While in C# you only have reference types. And you may get headache from pointer bug.
  • You also have to manage the allocation of memory manually. And there is a chance that your program will experience memory-leak if this is not done properly. In C#, every object is garbage-collected, automatically.
  • The declarations and definitions of classes are usually separated in header file (.h) and source file (.cpp or .cc). This will cause a little confusion at first.
  • You will not have so many base class library support in C++ as in C#. For example, you will not have HttpRequest class built-in in C++.
  • Therefore, You will have to use a lot of external libraries and know how to deal with .dll or .lib.
  • C++ has no Interface as in C#. You will use abstract class (and multiple inheritance) instead.
  • string in C++ is a char array or pointer to char.
  • There are some algorithm and data structure available for use in Standard Template Libary (STL.) But it takes time to learn before you can start using it efficiently :)

You can also learn C++/CLI to mix your .NET code and native C++ together to get the best of both world.

m3rLinEz
you don't want use multiple inheritance ...
Ilya
I agree with you Ilya :)
m3rLinEz
If he's worked in C previously, pointers and memory management should hold few surprises.
jalf
A: 

With respect to the language implementation differences -- and I think that you will need to be careful with things like memory management, declarations in headers, etc. -- I think the hardest thing to deal with is the extra overloading of special characters in the syntax. After many years of writing C# code, the things that I stumble over most are all those extra *, &, and <>'s kicking around. My first reaction is that C++ code looks a lot like a big regular expression.

I'm sure that once you've been using it awhile this goes away, but I don't do enough C++ anymore to be comfortable that I know exactly which symbol to use in every case -- am I passing in a pointer or a reference to that object?

The other big gotcha, when reading other people's code anyway, is operator overloading. I know that you can do it in C#, but I've rarely seen it done there. May be things have changed, but I used to see a lot of operator overloading in C++ where +/- would take on some weird effects. Other than some fairly obvious wins (like string concatenation) I think that this is really a dubious feature that I could do without -- in both C++ and C#.

tvanfosson
+2  A: 

I went from Asm to C, C++, ... and most recently C#. It's relieving being able to instantiate objects and just return them from a method or property. Typically, neither implementation nor user code needs to worry about freeing that memory. Also, there's no reason to return a status code, like HRESULT, in most cases because if there's a problem you throw an exception and let the user code handle it if it wants.

Having recently switched back to native C++ code for my last project, I truly miss garbage collection and exception throwing.

However, I do like C++'s templating capabilities. C# should one day expand on this technique.

spoulson
Why don't you use C++ exceptions?
Rob
Native C++'s exception handling is not as powerful as that in the CLR. I haven't found much use for it, since I'm used to throwing exceptions the CLR way.
spoulson
A: 
  1. Memory management
  2. More complex syntax
  3. Memory management
  4. Less tool support than C# for the entire OOP lifecycle.
  5. Memory management

And did I mention memory management?

I've always thought it interesting to use the marketplace as an indicator of the perceived needs of a segment of the population. Considering (for the sake of contrast) the VB market, it would appear that component libraries are the main emphasis. However, since earliest days, the dominant offerings in the C++ (and C) market seem to have been memory management, leak detection, and code quality tools (e.g. lint-like inspectors).

joel.neely
+1  A: 

I see several people pointing out memory management as a big problem because you will have to do it by hand. Well, don't believe them, this is wrong. Unless you are in an exotic/old-fashioned environment, C++ has tools that help us to manage the memory (as well as any other resources) implicitly, and deterministically. See boost/std::tr1 shared_ptr<> and RAII.

The big difference with GC collected memory: you'll have to take care of the cycles yourself.

Regarding multiple inheritance, once you've grasped what the LSP implies, it is not much of a problem either.

I'll have to concur with pheze's message: Accelerated C++ is a must read if you want to teach you how C++ can (/should?) be used.

Luc Hermitte
A: 

Circular references between classes [in C++]. OOP in C++ is really half baked if you ask me.

edit: Okay so some more detail is in order I suppose. Say you have: class Foo and class Blah. Class Blah references class Foo, class Foo references class Blah. Suppose you go the naive route you might implement it like this:

#include <blah.h>
class Foo {
    Blah blah;
    ...
}

and Blah:

#include <foo.h>
class Blah {
     Foo foo;
     ...
}

That probably won't work. Instead, you need to use forward references, i.e. Foo becomes:

class Blah;

class Foo {
    Blah blah;
    ...
}

If you do some googling for "circular references in C++" you'll see why I mentioned it in this question. Now stop voting me down will ya...

wds
Not sure why you seem to think C# can't have circular references. Needless to say, you're wrong (http://blogs.msdn.com/nickmalik/archive/2005/03/18/398601.aspx).
Matthew Flaschen
Hmm no I'm talking about circular references between classes in C++, i.e. the need to not just blindly include header files thinking they're just like plain imports. I'll edit my question to reflect this.
wds
+12  A: 

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. :)

jalf
+1  A: 

Jalf has it totally right - coming from a C/C# background, you practically already know all the basic C++ you need, and you know OOP too, so you're as good as done.

There are 2 things that come to mind that will be new to you though:

  • RAII: this lets you have automatic memory management, you no longer have to remember to free everything you malloc. Cool huh! It also helps with every other resource, you no longer have to remember to close that socket, file, DB connection - RAII does it for you. Neither C nor C# have this.

  • STL/Boost: this is the 'C++ class library', full of useful utilities and bits. All the standard containers are in STL (like 'dictionaries' and 'arrays' and 'lists') along with algorithms that you can apply to them (eg if you have a list of data items, you can provide a small function object (called a functor) and then pass both to a generic algorithm. This is really powerful, you can do a ton of work using it).

gbjbaanb
+1  A: 

The main different is that C++ is value based while C# is reference based.

In C#, when you pass an object to a method, you are actually just passing a reference, so the calling method and the called method are both looking at the same object.

In C++, when you pass an object to a method, a copy of that object is made, and the entire copy is passed to the method. Changes made by the called method to the copy do not affect the original in the calling method. The reference behavior can be simulated in C++ using the reference syntax:

void somemethod(someclass& obj);
James Curran
I'd say than reference behavior can be obtained with pointers, but references offer a better solution. My rationale is that, while they are called references, in both Java and C# _references_ __are__ pointers
David Rodríguez - dribeas
Matthew Flaschen
It's a "Simulation" because the reference syntax does not make C++ a reference-based language, but does give many of the same features.
James Curran