Changing the Unchangeable


Last week I asked you to please make member functions const whenever possible. But constant doesn’t always mean constant.

Declaring an object const is a way to tell the compiler that this object cannot be changed whatsoever. What you actually try to express might however be a logical immutability, that the meaning of the object should not change. That doesn’t necessarily imply that none of its member variables can be changed.

The most common example is to cache the result of an expensive operation. To expand on last weeks example:

class Whisky {
public:
  Smell smellIt() const;
  Taste tasteIt(int ml);
};

Imagine that computing the smell of the whisky is a complicated operation [1], that you don’t want to do every time someone smells it. You might want to introduce a private member to hold a cached description of the smell. This member must be possible to change, to be able to write the cached value. Computing and storing this value does however not logically modify the object, so it should be possible to do even for const objects. To allow for this, use the mutable keyword:

class Whisky {
public:
  Smell smellIt() const;
  Taste tasteIt(int ml);
private:
  mutable Smell* smell;
};

The definition of smellIt() would now look something like this:

Smell Whisky::smellIt() const {
  if (!smell)
    smell = computeSmell(); //Assume this function exists and returns a new, dynamically allocated Smell object
  return *smell;
}

Exactly how you do the caching is up to you, but if you use a simple pointer (and not for instance a shared_ptr), you must remember to delete smell in ~Whisky().

Posted in C++. Tags: , . 2 Comments »

Please Make Member Functions Const Whenever Possible


When you write a member function that doesn’t modify the object it operates on, please make sure to make it const.

class Whisky {
public:
  Smell smellIt() const;
  Tase tasteIt(int ml);
};

Smelling the whisky doesn’t modify it, so I made smellIt() const. Tasting does however modify it (there is less left in the glass), so tasteIt() is not const.

Why does this matter? If someone makes a const object of the class, they might still want to call some methods on it. For instance, a good practice for a method is to take objects by reference to const. And then you will only be able to call const methods:

void describeWhisky(const Whisky& whisky) {
  std::cout << whisky.smellIt();
}

This would not be possible if smellIt() was not const. The same goes for using const_iterators and a lot of other situations, so please remember to add const whenever you can, even though it doesn’t make a differece to you then and there.

Edit: I posted a follow up, on how you can change some parts of an object, even if it is const.

Posted in C++. Tags: . 4 Comments »

Static and Dynamic Polymorphism – Siblings That Don’t Play Well Together


Static and dynamic polymorphism might sound related, but do not play well together, a fact I had to deal with l this week.

This is the situation: We have a set of worker classes, that work on a set of data classes. The worker classes can do different types of work, but the type of work is always known at compile time, so they were created using static polymorphism, aka templates.

template &lt;typenmame WorkImpl&gt;
class Worker {
...
};

WorkImpl decides the details of the work, but the algorithm is defined in Worker, and is always the same.

Those are the workers. We then have a pretty big tree of data classes. What kind of objects we need to deal with is not known until runtime, so we are using inheritance and virtual methods for these.

  A
 / \
B   C
|
D 

etc.

A has a virtual method fill() that gets passed a WorkImpl object, and fills it with data. fill() needs to be implemented in all the subclasses of A, to fill it with their special data. Bascially, what we want is to say

class A { 
  template  &lt;typename WorkImpl&gt;
  virtual fill(WorkImpl&amp; w) {...} //overridden in B, C, D etc.
};

Can you spot the problem?

Hint: When will the templated fill() methods be instantiated?

There is no way for the compiler to know that classes A-D will ever have their fill()-methods called, thus the fill()-methods will never be instantiated!

One solution to this problem is to make one version of fill() per type of WorkImpl, in each data class A-D. The body of a fill() method is independent of the type of WorkImpl, so this solution would lead to a lot of unnecessary duplication.

The solution we ended up with was creating wrapper methods that take a specific WorkImpl, and just calls fill() with that argument:

class A {
  virtual fillWrapper(OneWorkImpl&amp; w) { fill(w) };
  virtual fillWrapper(AnotherWorkImpl&amp; w) { fill(w) };
  template &lt;typename WorkImpl&gt;
  virtual fill(WorkImpl&amp; w) {...}
}

In this way we minimize code duplication, and still make sure the fill() methods are always instantiated.

Question: Can we get away with defining the wrappers in A only? And if not, when will it fail?

Answer: We can not. If we only define the wrappers in A, fill() will never be instantiated in B-D. Everything compiles and links, but at runtime, it is the A version that will be called for all the classes, leading to a wrong result.

Finally, I should mention that another option would have been to refactor the worker classes to use dynamic polymorphism, which would basically solve everything, and allow us to get rid of the wrapper functions. But that would have been a bigger job, which we didn’t have time for.

New Job, and Windows Survival 101


This Monday, I started in my new job at SPT Group. Their main product is OLGA, a multiphase flow simulator which has been around for thirty years, is the current clear market leader, and some say it laid the foundation for the entire Norwegian petroleum supplier industry.

This means I get to work in an advanced scientific/engineering domain, with some really smart guys, write new code, work out the intricacies of legacy code, and collaborate with both technical customers and partners like IFE. Plenty of challenges! And they seem to get a good score on the Joel Test, always a good sign.

The first challenge however, is surviving as a developer on Windows. Yes, I am now working full time in Visual Studio on a Microsoft Windows 7 workstation, which I am sure boggles the mind of people who know me well. Here’s a short survival guide:

  1. Get a decent computer. In my previous job, the main reason I tried to spend as little time in Windows as possible, was because I had a singe core laptop with 1 GB RAM, running Windows, antivirus, backup and all sorts of automated updates and configuration management software. Now add the development environment, and guess where it leaves you. My current workstation is an eight core Xenon with 8 GB RAM, and Windows feels almost as snappy as Ubuntu.
  2. Launchy is kind of like Gnome Do. You won’t have to navigate the start menu every time you want to launch a program, nor keep it in the taskbar, you just press Alt+Space, and start typing the first few letters of what you want to launch. In addition to launching applications, it can open documents and folders, act as a quick calculator, search the web, and more. It is also intelligent, so your most commonly used commands usually only needs one typed letter to launch.
  3. VirtuaWin is my favourite solution for multiple desktops on Windows. I have tested several, but this one is fast, open source and sufficiently advanced, with customizable keyboard shortcuts.
  4. AutoHotKey is a “free keyboard macro program. Supports hotkeys for keyboard, mouse, and joystick. Can expand abbreviations as you type them”. I currently just use it to fix the Windows window-manager, so you can alt+click anywhere in the window to resize it or move it around, without having to find the window border first. Here is the script I’m using for that. The tool is really much more versatile than this, for instance I once added “reload document” to the Foxit pdf-reader with a few lines of scripting.
  5. AstroGrep is a nice grepping tool. Grep is probably the command I miss most on Windows, and if you don’t want to go full CygWin, this is a quick and easy solution.
  6. gvim Update 6. Aug.: I forgot to mention vim, my trusty allround editor. I am developing in Visual Studio these days, but vim is great for other text editing as well.
  7. CygWin gives you the most common Linux tools, shells and commands. If you are used to doing a lot of ad hoc shell scripting, this is a must-have. I have used it quite a lot before, but I haven’t installed it here yet. When most of what I do goes on inside Visual Studio, the need hasn’t been there yet, AstroGrep has been enough. In projects where I do more command line stuff, I can’t live without it. Update 6 Aug.: Enough already, I miss bash, sed and awk. Installing CygWin now… Update 9 Aug.: If you decide to try out Cygwin, make sure you install a better terminal than the default Windows one, like mintty or rxvt.
  8. A good terminal Is there a good terminal for Windows, without running CygWin? I would appreciate some recommendations.