Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

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.

share|improve this question

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
1  
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
2  
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

12 Answers 12

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.

share|improve this answer
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

Mostly about garbage collection. You have to release every dynamically allocated memory.

One more thing is that pointers can be invalid. In C# reference can point only to object or to NULL. In C++ pointer can point to anywhere.

Array bounds check. No one grantees that you don't overcome the boundary.

In C++ you can pass object by value, not only by reference. It may cause useless copying.

share|improve this answer
7  
By "you have to release," you mean "you must make sure to always use RAII containers to ensure resources are released correctly," right? You should never have to explicitly release a resource. –  James McNellis Feb 15 '11 at 18:59
    
@James McNellis without boost it may become problematic. you can't have vector of auto_ptr, for example. and other libraries not always follow RAII, so you either create wrappers or manage resources by yourself. –  Andrey Feb 15 '11 at 19:02
2  
In C++ you can pass object by value, not only by reference. It may cause useless copying. - In the C# everything is passed by value as well, you are simply passing a copy of a reference in the case of reference types. Also, in C++ you can certainly pass a reference or a pointer. Not sure what you were trying to say with that line. –  Ed S. Feb 15 '11 at 19:03
1  
@Andrey: writing a RAII wrapper is something like 5 lines of trivial code, though. That's usually easier than manually managing resource lifetime. –  jalf Feb 15 '11 at 19:06

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!

share|improve this answer
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
3  
@BlueRaja: Not if you actually know the language. –  Billy ONeal Feb 18 '11 at 2:52

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.

share|improve this answer

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.

share|improve this answer

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

share|improve this answer

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.

share|improve this answer
    
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

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.

share|improve this answer
    
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

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

share|improve this answer

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.

share|improve this answer
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
2  
"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

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.

share|improve this answer

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 http://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.

share|improve this answer
    
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

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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