I'm currently teaching myself C++. I'm very proficient at C#, and was wondering which common practices in C# can lead to difficulties in C++, and what a C++ programmer should do instead.

migrated from stackoverflow.com Feb 18 '11 at 0:55

This question came from our site for professional and enthusiast programmers.

  • 1
    wouldn't it be more helpful to ask what you should do instead, rather than simply "what are the errors I'll make"? Most of the answers you're getting are just telling you why you'll hate C++. – jalf Feb 15 '11 at 19:04
  • 2
    I'm not asking "what errors will I make". I'm asking of the habits that I'v learned using C#, which ones will cause me problems in C++. – Donny V. Feb 15 '11 at 19:12
  • 3
    Using C# in the first place (just kidding). ;-) – Thomas Matthews Feb 15 '11 at 20:24
  • 2
    @James: I disagree. I don't see a problem with subjective questions, as long as it is reasonably possible to distinguish between a "good" and a "bad" answer. (Practically every question is subjective on some level anyway). I'll edit the question text a bit and vote to reopen. – jalf Feb 16 '11 at 2:41
  • 2
    This question is like asking "what common practices speaking Spanish can lead to difficulties in Italian". Languages have a common ground, but if you are trying to adapt Spanish to speak Italian you would always have a weird Spanish accent and sometimes even build sentences in a completely awkward way for Italian. – Trinidad Feb 17 '11 at 13:10

11 Answers 11


PS: Since I talked about new, delete, raw memory etc, then let me add an interesting difference between C++ and C# :

In C++, this is a pointer, while in C# this is a reference!

  • 3
    using struct is pretty RAIIsh in c# – Andrey Feb 15 '11 at 19:00
  • 1
    Would help if you include a link to an explanation of the RAII acronym. The Wikipedia article is good (en.wikipedia.org/wiki/RAII). I'm guessing that most people who are new to C++ are also new to that acronym, so it would help if you provide a link that they can easily follow. – A. Levy Feb 15 '11 at 19:02
  • 23
    I'd say you should swap the order of the parts of your answer. If you know RAII, you hardly ever have to deal with new and delete. – jalf Feb 15 '11 at 19:05
  • 1
    No matter how much you study C++ first, you will always end up writing code with undefined behavior; then when the code behaves differently in debug and release, you will spend hours debugging, certain the entire time that it's a compiler bug. – BlueRaja - Danny Pflughoeft Feb 17 '11 at 17:20
  • 4
    @BlueRaja: Not if you actually know the language. – Billy ONeal Feb 18 '11 at 2:52

The most fundamental one is of course related to the lack of a garbage collector:

don't use new any more than necessary. Understand the RAII idiom: allocate your objects on the stack (without using new), and let their destructors take care of cleaned up allocated memory for you. Or use smart pointers to handle some of this for you.

Other than that, I'd say there are some stylistic issues you should get used to. C# is still, despite its flirtation with functional programming, an OOP language.

C++ is a multi-paradigm language, and in modern C++, OOP just doesn't play a very big role. You should definitely look into generic programming, though. Understand how to use the STL (the data structures, iterators and algorithms in the standard library). And feel just a bit dirty when you write a virtual function.

  • 1
    The runtime cost is part of it (it's there in any language, but the JIT can often eliminate it in .NET), but mainly it's because C++ has some some alternatives that may be preferable. In C++, you can often get away with using static polymorphism (templates) instead of dynamic (virtual functions). A problem with dynamic polymorphism is that you have to refer to the base object by pointer/reference to avoid slicing, and that you lose type information that can be preserved with static polymorphism. – jalf Feb 16 '11 at 2:39
  • 4
    And on a personal note, I've just found that I hardly ever need virtual functions. I occasionally make a function pointer, and I sometimes use std::function/boost::function, but rarely virtual functions. I'm not saying they shouldn't be used though, just that the alternatives should be explored, because unlike in C#, they're not the only tool you have. – jalf Feb 16 '11 at 2:40
  • 2
    There's little decoupling in OOP, in my experience. If a class D is derived from a base class B, then D has to know about B. They're not uncoupled. But yeah, of course it's all relative. Some people rely more on OOP than others, and "not a very big role" is a kind of vague statement too. But yeah, the right tool for the right job. I just wanted to emphasize that in C++, you have to choose between several tools which could all be used to do the job. – jalf Feb 17 '11 at 3:36
  • 1
    Then A has to become a template, meaning its implementation is exposed, and in large-scale systems, build time will be very high if you do this frequently. Templates aren't all roses and green pastures; they come with tradeoffs, and you have to use your judgement. So I don't think a comment like, "And feel just a bit dirty when you write a virtual function." is any more constructive than, "And feel just a bit dirty when you write 'template<typename T>'.". – Ben Feb 17 '11 at 19:52
  • 3
    "C# is still, despite its flirtation with functional programming, an OOP language": C++, despite its flirtation with functional programming, is definitely not a functional language. – Giorgio Jan 4 '13 at 14:45

Automatic memory management and garbage collection is probably something you could be missing in C++. But IMHO what you will miss most is the consistency of the .NET framework where you have been taking lots of things for granted simply because they are built into the BCL.

  • 15
    I think it's implicit in the question (even if the OP doesn't actually say so), that he's interested in how to overcome bad C# habits, not just in a listing of "things a C# programmer will hate about C++" – jalf Feb 15 '11 at 19:10
  • 1
    Yeah I already know that C++ doesn't come with a GC. – Donny V. Feb 15 '11 at 19:14
  • @jalf, when you have taken the habit of having the runtime release all your objects we can say that you have taken a bad habit as when you start coding in C++ chances are you will do the same and this will bite you. That's why I thought it's worth mentioning as a bad habit. – Darin Dimitrov Feb 15 '11 at 19:16
  • 1
    @Darin: and it absolutely is. I'm just saying it doesn't really help the OP much, because it doesn't tell him what to do instead. How does on deal with the absence of a GC in C++? And likewise, how does on come with the "lack of consistency" you get from the .NET framework? – jalf Feb 16 '11 at 2:48

The biggest problem I've seen is the tendency to new objects all over the place and use them on the heap. Sure, they may take a lot of care deleting them as there's no GC, but the problem is allocating on the heap in the first place. C++ works better putting stuff on the stack and copying it about. If you do still need a single shared object, use shared_ptr to contain it.

Mind you, this isn't exclusive to C# devs, I've seen a a few web devs do the same kind of thing.

  • What do you mean by " putting stuff on the stack and copying it about"? Can you give some examples or links. – Donny V. Feb 21 '11 at 16:17
  • 2
    I mean, treat every variable as a value object - not a pointer or reference to a heap-allocated object, and never use new. (subject to when you do want to do those things). – gbjbaanb Apr 12 '11 at 8:24

Garbage collection is a big one, but if you use smart pointers you can avoid most of the trouble with that.

A more pervasive issue is that of exception safety. This isn't so much a C# habit that will get you in trouble, but a lack of one. In C#, you get safety with using blocks and finally handlers. C++ has neither. What you have is a technique called RAII (resource acquisition is initialization), where classes are carefully designed so that their destructors clean things up. So rather than use a using block to open a file, you'll stack-allocate the file object and the destructor will flush and close the file. It takes care to design and use classes in this way, but once you form the habit your code can be pretty safe. It's just a different approach. In general, the fact that C++ has stack allocation of objects will necessitate some adjustment.

  • I was reading Google's c++ style guide and they say not to use pointers but to use an object directly as a field or local variable. Is that better? – Donny V. Feb 15 '11 at 19:09
  • 17
    Google's C++ style guide is far from a definitive source. Frankly, I wish they'd never published it because now people keep quoting it as an authority and it's just not. In this one case though, they're right. Prefer value objects over pointers. – Crazy Eddie Feb 15 '11 at 19:27
  • 1
    Yep, prefer value objects over any kind of pointer. Prefer smart pointers strongly over bare pointers. Only use bare pointers when you need to interop with old/broken APIs. And Qt has a nice solution for value types with data sharing that give you most of the benefits of pointers with the benefits of value types. – Michael Ekstrand Feb 15 '11 at 20:08

RAII is definitely one of the key aspects of C++ to learn. Other posters have described it, but I will add that it is quite similar to C#'s IDisposable interface combined with the using keyword.

Be wary of char and string types in C++, they have grown up from many years of (bitter) experience and there are different types. In C# they're all Unicode (I forget the encoding), but in C++ a char is usually dependent on the system's code page. For example, US-English Windows uses a code page of Windows 1252 by default for non unicode programs. Code pages are difficult to manage and error prone so use wchar_t and the STL's std::wstring. Also be aware that the size of char and wchar_t is different between different compilers. Many Linux based C++ compilers use a different character size and the advice is different again! See https://stackoverflow.com/questions/4588302/why-isnt-wchar-t-widely-used-in-code-for-linux-related-platforms for more info.

Be aware of the scope of variables and when they will be destructed. It is generally bad practice to do return new object() as the caller might not realize they need to clean up the return value.

Avoid the use of naked pointers, instead use unique_ptr or shared_ptr + Use make_shared<>() to create a shared_ptr. Unfortunately there is no unique_ptr equivalent at the moment.

Learn about move semantics - they can help a lot with RAII. I'm not aware of an equivalent in C#

Understand what an opaque pointer is. If you're using the Windows API you'll come across a lot of these in the form of HANDLEs.

Be wary of storing lists (e.g. std::vector or std::deque) of objects which can be inherited as this can lead to slicing where the inherited part of the class is sliced off so only the declared type is left.

  • ISO/IEC 14882:2011 § 3.9.1 Objects declared as characters (char) shall be large enough to store any member of the implementation’s basic character set. If a character from this set is stored in a character object, the integral value of that character object is equal to the value of the single character literal form of that character. It is implementation-defined whether a char object can hold negative values. From this quote we can understand that the char encoding is not ASCII but the implementation basic character set. It just happened to be ASCII on some (most) platforms. – authchir Jan 5 '13 at 2:36
  • Thanks for the comment. I've tried to add enough relevant information in without going over the top. I hate that strings are so complicated in C++! – Steve Jan 5 '13 at 13:10

Forget about try-(catch-)finally and get used to do resource allocation/deallocation via constructors/destructors (RAII).

Avoid programming in C++ as if it was C#, that's the practice you should avoid. Actually learn the language, it's quirks, the good parts and it's idioms.

The most obvious would probably be taking garbage collection for granted. Un-referenced objects have to be manually disposed in C++, but in C# you have the GC to take care of them.

Memory management, passing conventions and pointers, although if you use a library like Boost it's probably less of a problem. However, if you're teaching yourself C++ it's probably a good idea to not use any libraries and learn the basics first.

Memory management, watching out for memory leaks and getting used to not having automatic garbage collection.

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.