Try not to use getters and setters

Avoid getters and setters. Why? Because they break encapsulation. If you need them, it’s usually a sign of bad code, “code smell”. In some cases, they can be useful, but in general, avoid them. If you think you need them, think about how else you can avoid them. Perhaps using “friend” as long as they’re behind the same architectural boundary interface. Or perhaps the class itself could do the work instead of exposing it’s privates to the world. Using getters and setters is almost equivalent to just making the members “public”.

Where to put doxygen comments

I’m awesome
This is an “ah ha!” moment for me. For some reason, I felt that it was better to place all of my function method comments inside the cpp files instead of the header file. I felt it was cleaner, and it looked nicer because the header file was nice and compact and formatted neatly. You could glance at the class and immediately determine what public function methods you were supposed to use.

I am no longer awesome like I thought
Well, until I realized that, after you compile the library and distribute it with the header file, there are zero comments for the end user on how to use the API, unless you’ve built the doxygen comments already and also distributed it. This makes it a hassle for the developer who now has to go onto a website or open a .chm file for documentation. It’s rather clumsy.

There is a nasty trade off for this though. If you put all the comments in the header file, the user may now have to scroll around just to find the public API. It may not be nice and neat anymore and it feels cluttered to me. Maybe you can use visual studio’s “#region” stuff to help though.

Put doxy comments inside the header file for the end user, not the cpp file, where no one will be looking or possibly even have access to. Alternatively, put the comments in the cpp file, but make sure you’ve built the doxygen documentation for the API. I say the header is better because the developer won’t have to jump out to a website to get documentation. Another rason is because you can mouse over a function in visual studio and it gives you a synopsis of it with the tool tip. Yay.

Project paths made easy with environment variables

I don’t know about you, but I get very frustrated when I just want to use a library. I don’t feel like setting up the paths for every project that uses the library. I just want to get in there, and start coding. This makes the problem a lot easier to deal with and saves a lot of time. This is probably obvious for most developers, but I didn’t figure it out until I started installing a bunch of libraries and SDKs, and then it “clicked” for me what they were doing and why it’s so much better. I used to think that anytime the install directions said to modify or add an environment variable, it was just going to be a big hassle, so I never did it. Boy was I wrong!

If you have a project that requires an SDK or a library to be installed, there’s a good way to go about setting it up in your project, and a bad way. The good way is to set up an environment variable to the directory with the SDK or the library installed. The reason this is a good idea is because you don’t have to have any absolute path information in your visual studio / make file solutions. So when you install the dependency/SDK, you also set up an environment variable to the location it’s installed. Some SDK’s do this automatically for you, which is nice. If your project is cross platform, this will save you and your users (if they want to recompile your code) a lot of frustration and avoids having “special case” logic in your make files.

If you think that the solution is to simply use relative path names in the project/solution, you’re wrong. The SDK could be installed anywhere on a different person’s machine, particularly if it’s a cross platform project. Using the environment variable approach also alleviates having to distribute the SDK with your project as well (if you chose to use relative paths). As long as your project doesn’t depend on a very specific version, this approach is better.

So basically, you set up the environment variable that points to the SDK/library, and you reference the environment variable inside your project or cmake files.

So, let’s say you downloaded this new SDK and installed it into C:\SDKs\awesome_sdk. Inside of the awesome_sdk directory, you will probably have folders such as “bin”, “include”, “libs”, etc.

So now, just create an environment variable called “AWESOMESDK_DIR” that contains “C:\SDKs\awesomesdk”. Now, within your project, cmake, or premake files, you set up the include directory to point to $(AWESOMESDK_DIR)\include. You do the same with the libs. You also probably want to add $AWESOMESDK_DIR\bin to the $PATH environment variable as well. The “bin” directory probably contains .dll files and possibly other tools. This will allow you to run the executable regardless of the directory, and will also prevent you from polluting your system32 directory with various dlls. Obviously, you’ll have to distribute the dll’s with the .exe when you’re finished though.

Now, when someone downloads your sources / project on their computer, they can install the dependency SDK anywhere they like on their own machine. Your project that they downloaded is smaller because it doesn’t include the dependent SDK. As long as they set up the environment variable properly, when they go to build the project/solution, it should build without any project changes.

There is one thing left that you may want to do. Depending on the development tools that you’re using, there is usually a way to do this “globally”. What I mean is that it’s possible to only have to do this once, and every project that you make, from here on out, will automatically be using the new SDK, automatically. For example, in visual studio 2010, you go to the “Property Manager” tab and right click on “Microsoft.Cpp.Win32.user” and click “Properties”. This property page will inherited for all projects that you make from here on out. Setting up the include directory to be $(BOOST_DIR)/include on this property page, will mean you never have to set it up, for any project, ever again! Of course, your situation may change depending upon whether or not you use CMake or premake or something like that.

Setting up an environment variable in Windows
Setting up an environment variable in linux

Easy casting with boost::lexical_cast and std::to_string

If you haven’t used boost, you need to start using it. Actually, if you’re not using the standard C++ library or STL, you should learn how to use most of that first. Since starting my new job at D4D Technologies, I have been using a lot of boost. One of the most useful is boost::lexical_cast<>().

Basically it allows you to cast from one data type to another by specifying a specific data type to cast to. The old way of casting from a float to a string, for example, is to use string stream. This requires about 3 lines of code and it’s messy. Alternatively you could use the nasty C-style sprintf(), which has it’s own problems.

The new way is to just do this:

The newest C++11 standard has something of value that is similar, but there are a lot of variations.
The difference is that boost requires a datatype, whereas the C++ library functions do not.
One issue I have with them is that they’re all named differently and you have to look them up. But they work like this:

These are all of the new C++ 11 converter functions, to and from string.


Keeping track of constants

This is a simple little trick that I learned while I was at Game Circus. Basically, the goal is to never have any string constants or number literals littered throughout your code. Instead, you want to make one constant and place it at the top of the file. This is usually an obvious idiom to most programmers, but you may not realize how important it is.

The reason you want to do this is because if you used, for example, the value 0.004f in a few places within your cpp file, but you want to change that value, you’ll have to change all the places where you used it. It’s easy to forget one or two though, which is the problem.

So the idea is to group them all together at the top of the cpp file and make them static and const. It’s much easier to do this if you have primitive data types versus classes. It’s also better to have the value stored in the cpp file. If you store it in the header file, every time you need to change it, it has to recompile all the cpp files that include that header. So the compile time is actually faster if you keep them defined in the .cpp file like this.

The reason it’s good to make the value static is because it will only make one copy of it for that class. You obviously want it to be const because that will guarantee that it won’t change.

Header file.

Cpp file.

Of course, it’s up to you to change things around. For example, you may want to make them private instead of public. You can move them outside of the class too, or just within the namespace, but this will pollute the namespace, unless that’s your intent.

As a side note with regards to localization: Ideally, you would put all of your strings in something like a spreadsheet. One column for “English”, one column for “Spanish”, etc. Then you simply implement a “fetch” function that will automatically grab the correct string based on a language setting.