Learning C++ (for the right reasons)

edited in General
Right, so there have been plenty of posts regarding technology choices, and how Unity/Game Maker what have you are the one true way. I tend to agree with these posts - starting from scratch in C++ is just madness if you're a single indie developer.

So here is my dilemma - from time to time there are opportunities that pass by me because I'm not proficient in C++, particularly in the international arena. So I would like to ask what a good starting place would be for an experienced programmer proficient in C# and many other languages?

Without a doubt I think the best way to actually "learn" a language is the throw yourself in the deep end and take on a project. I'm kinda hoping there are at least some approachable resources that outline the different design philosophies and working practices of the different languages so I can start familiarizing myself with C++. Also note, I'm not looking to learn about doing low level graphics and engine programming, more just to get an impression of what I'd actually be in for and what concepts I'd need to get my head around if say I was working a bespoke game engine. STL, malloc, templates, pointers and references. All that jazz.

Comments

  • edited
    I learned theoretical C++ at university. Then I learned actual, full-contact game development C++ under the watchful eye of @AngryMoose at I-Imagine. At that point I'd already used lots of different languages and engines, so I think that's a similar spot to where you are now. The stuff below is from memory, so certain parts, specifically templating, might be horribly wonky - I value being corrected! These are the cliff-notes that I wish I'd had when I started reading C++ tutorials and the like...

    Theoretical C++ is all about coding conventions and what your program is actually doing, that's why lots of C++ courses start after some sort of Assembly module, then a C module, before getting to the extensions and object-oriented stuff. That's why C++ tends to always veer towards low level implementation angles - because that's what it gives you to work with, everything is unrolled and you have to decide how you want things to fit together.

    In C++ everything is about memory. How you access it, what you want to do with it and where that memory actually is on the machine:

    Pointers are memory addresses, how they behave depends on what is actually at the memory address they're pointing to: You can call a method on an object, if C++ has been told that it should expect an object at that location (that's what the pointer->method() notation does) if it's just a number at that address, then you can treat it like a number. That's why the type of a pointer is so important - it tells the language how much memory that pointer is actually "pointing to".

    Referencing and dereferencing are tools to figure out if you should be paying attention to a variable's memory address or the contents of that memory. Finding the reference of a variable will give you back that variable's memory address, essentially giving you a pointer to it. De-referencing a pointer will give you the contents of that memory address, usually as a copy in a new variable (so hence new memory location). Most managed languages have similar constructs around passing parameters by reference (ref in C#) and value (dereferenced copy, val in C#). There are all sorts of different reasons to mess with these things, but generally if you have to it means that something is broken in the system design.

    Malloc is there to give you access to chunks of memory. Dealloc nukes memory chunks. The "new" operator in C++ is essentially a custom malloc call that gives you enough memory to store the object you told it to give you, but it also finds a place to store that object. Because you're in direct control of all your memory, you have to make sure that you kill objects when they're not in use anymore, otherwise your memory needs will keep growing and horrible shit starts happening. Many people use malloc to create their own versions of garbage collection mini-implementations, so you might have X memory allocated for a particle system and maintain your own pointers for where new particle system objects should go inside that pre-allocated chunk.

    Templates are a way to try and deal with shifting memory size requirements where they might not be known beforehand at the time of writing. Things like strings and arrays regularly cause havoc in C++, strings have no real "set size", so they need to have a special ending character, for instance. Templates basically allow you to write stuff independant of the size of a particular memory chunk, so you could write a template for a linked list and then fill in the thing that linked list is actually storing at run-time. Generics in C# are templates, so Unity's List<> is a template implementation.

    So, working with C++ is all about keeping track of memory, having access to memory while debugging is super-important! If you can't step through your code and see how memory is actually changing in response, run far, far away... You have to destroy things and know how big things are, know where you're putting them and why you want them. That counts as much for variables as it does for object storage. One of the biggest issues you'll have with a C++ program is doing the equivalent of keyhole surgery in a chunk of memory somewhere, except you're operating on a brain when you thought you were fixing a knee problem, so everything goes horribly wrong. That's why a lot of C++ architecture rambling talks about making sure you can't poke memory you shouldn't be able to poke - Const and dereferencing and protective casting and all that jazz.

    Then there's all the stupid pre-compiler stuff that gets horribly annoying, I would ignore most of those as showing off, especially the one-line if bullshit. The only exception is headers. Header files are essentially instructions for the compiler so that it can know what you're going to be populating with code later on, it's almost like a sizing chart for your program combined with a cheat-sheet so that you can call other methods without your compiler going "but that doesn't exist yet!".

    Full-contact C++ is pretty much just like the above, except you're fitting into an existing system as quickly as possible. That means there will be code guidelines already in place, if they don't have a standards document, don't touch the project. That also means that there's probably a stricture against using new, under pain of death. And you might not get shot for using void pointers if you're not a complete lunatic with them.

    But yeah - it's all about memory.
    Thanked by 2hermantulleken hanli
  • @dislekcia thanks! That was a very boss answer. Wasn't expecting you to write all of that out for me. Apologies for the nerd snipe ;)

    As for possible corrections, I've heard generics are fundamentally different from templates - but that is just incidental hearsay. I'm sure there is enough similarity to warrant the comparison.
  • @TheFuntastic templates are compile time macros that create a new class from scratch using the patterns defined. On the up side you get compile time safe implementations on the down side you have ZERO reflection.

    A couple of other details you should be aware of. In C++ you can pass objects by pointer or create copies (the compiler will copy your class but does not do a deep copy so it can be troublesome). In most type safe languages you can not conveniently copy objects or structures. C++ organizes all classes and structures so you can simply copy the memory to a new location and you have a shallow copy of that object. (shallow meaning that if you had a pointer in that object to another the inner object is not copied only the pointer to is.)

    Essentially C++ memory management is your problem. this guide gives you a fair overview. http://en.wikibooks.org/wiki/C++_Programming/Memory_Management

    I release both Toxic Bunny HD and The Tainted both written in C and C++ and assembler mind you. There are some really neat tricks you can implement and you really can feel like a programming genius when you pull off the simplest of things. The memory management got to the point where we overloaded the new and delete methods of the sprite classes to assist with fragmentation of the heap.

    As @dislekcia pointed out you have to manage who owns what since any thing you use the new keyword or you malloc directly must be deleted when you are done with it. This requires you work in pasterns of ownership. Say a function you are calling requires a buffer. Consider this example. You call a method that loads an image and returns it to you. Now you have this chunk of memory that belongs to your code. How will you manage the scope of that memory what functions or objects will be responsible for deleting it when its no longer needed. You have to design your solution so that you can clearly identify when objects go out of scope and delete them when that happens.

    If you decide to do a project would love to see what and how it goes, I for my part love working in c++ but I don't have projects that really require that kind of control or can justify that kind of cost.
  • I like it. It can be fun, but don't expect to get anywhere fast (from my experience). Of course I taught c++ to myself - no formal education in c++. I believe that's the best way to learn ...but again, slow. :)
  • edited
    Like @dislekcia, I did my first stint of real-world C++ under @AngryMoose 's watchful eye. It's definiately something different alltogether from varsity C++, as dislekcia points out. Although I know what he says about memory management is true, my experience with the language was quite different, because of a handy cheat. I was (and still is) so afraid of the memory management stuff, which I thought was a bit above my head. So I kinda decided not to allocate any dynamic memory whatsoever, and write all my functions to take references instead of pointers, and see how far I could get. As it turned out, I got quite far. It's a severe constraint (collections cant take references, you can't make factories, you sometimes have weird things with other libraries,...), and not one I would recommend as "good practice"... but it may (???) be helpful in a transitioning stage. Memory management was totally a non-issue.

    But C++ has of course many other ways of screwing you around. The other thing that still scares me a little is how incredible difficult it can be to make certain design changes. I had many instances where C++ + my_own_cleverness == nightmare_from_hell. C++ is definitely the language where more upfront thinking and design is incredibly useful. This is also why a real-project is a good way to learn; those mistakes are useful to make. But like @tbulford said, it is a language that _does_ you make you feel clever, and I did get a lot of satisfaction from it.

    The one resource that became my bible is Bruce Eckel's Thinking In C++ (freely downloadable). (Are they a bit old now?)

    One other recommendation I can make is to look at a library or two relevant to the type of programming you do, and write some code on top of that, to get into it, perhaps, before starting an actual project. This will give you two important pieces information: First, a feel for the C++ compilation + integration process, which is by far the most complex of any language I worked with. Second, a feel for how to organise your code [architecturally] / data structures, and indeed, memory responsibilities.

    Anyways, good luck, and have fun :)
  • edited
    @TheFuntastic I would recommend learning and maybe starting with C++11 standard stuff... The changes really make C++ feel similar to other languages. Things like using auto, for each looping and lambda functions make life much much easier.

    Also... Dear god please use the new smart pointers! Every C++ developers lives have changed drastically by using them. Sure you should learn pointers and how to manipulate memory but 99% if the time using a shared pointer will just make everything *so* much better.

    [Edit:] You have no idea how passionate I am about C++11... It really has changed my life <3 (well when i can't use *any* other language that is :P)
  • Thanks guys. This is exactly the kind of input I was hoping for. Still have to address that nagging thought at the back of my brain that this might be a giant distraction from the business of building games if I don't in fact end up needing it. However I think If i find the right starter project to ease myself into it should be okay, plug in development or something like that.

    @creative360 sounds great, but how interoperable is C++11? Assuming the whole environment has to be written in it?
  • I know almost nothing about C++, except that I want to avoid it for as long as I can. But in case it helps (because really, I don't know enough to know whether this is useful or not), I've heard the Boost libraries are super useful and very popular, depending on what you're doing. In particular:
    Some of the most versatile parts are the shared_ptr (a reference-counting smart pointer that helps prevent memory leaks in pointer-rich code), array which provides a very convenient wrapper around C-style arrays of fixed size and other small odd bits which have been integrated into the next C++ standard.
  • edited
    @TheFuntastic Most, if not all, compilers now support c++11 including gcc/g++/clang and visual studio 2012(visual c++) I think support most of the new features... so I don't really know of any reason not to use it. It is also completely backwards compatible so any old c/c++ library will work with your C++11 code. Anyone else have further input?

    @Elyaradine That's pretty good advice in general, boost have many extensions which make life a little easier. A few of the C++11 standards were implemented in boost before the new standard came out (like the smart pointers). Personally I've never really used boost so I can't really talk about it with conviction.
  • For anyone who might find this post in future, this seems to be a quite a good starting point on C# to C++ dev (50 page pdf with a leaning to making win 8 metro apps) http://blogs.msdn.com/b/jerrynixon/archive/2012/02/20/c-for-c-developers.aspx
  • Not sure if this will be useful to someone, but there is a C++ course now on coursera:
    https://www.coursera.org/course/cplusplus4c
Sign In or Register to comment.