Refactoring with C++ 11

Refactoring with C++ 11

I would add delegating constructors and in-class member initializers to the list.

Simplification By Using Delegating Constructors and In-Class Initialization

With C++03:

class A
{
public:

// The default constructor as well as the copy constructor need to
// initialize some of the members almost the same and call init() to
// finish construction.
A(double data) : id_(0), name_(), data_(data) {init();}
A(A const& copy) : id_(0), name_(), data_(copy.data_) {init();}

void init()
{
id_ = getNextID();
name_ = getDefaultName();
}

int id_;
string name_;
double data_;
};

With C++11:

class A
{
public:

// With delegating constructor, the copy constructor can
// reuse this constructor and avoid repetitive code.
// In-line initialization takes care of initializing the members.
A(double data) : data_(data) {}

A(A const& copy) : A(copy.data_) {}

int id_ = getNextID();
string name_ = getDefaultName();
double data_;
};

C++ Refactoring, Extension Methods typedef

My suggestion will be to put related functions in appropriately named namespaces instead of making them static member functions of a class.

Examples:

namespace RenderAPI
{
// Put all rendering related functions here
}

namespace PersistenceAPI
{
// Put all read from disk and write to disk functions here.
}

namespace MySuperCoolBusinessLogicAPI
{
// Put all the functions dealing with your super cool business logic here.
}

migration to c++11

First of all: it depends on the policy.

Like all technologies, switching from something that works to something new is a risk in itself. Depending on your mindset and the criticity of your project, the degree of risk you accept may differ (for example, I use the top of tree version of Clang for personal projects but a mature gcc at work).

Personally, I would recommend not diving head-first for production ready projects, but instead perform a piecemeal selection of the features that work.

You mentionned:

  • rvalue references & perfect forwarding
  • default/delete
  • variadic templates
  • type inference (auto/decltype)
  • template aliases and constexpr

VC++11 comes with support for many C++11 features. You could start using rvalue references and type inference right now, for example. And those can be used with gcc 4.5.x branch if I recall correctly, which is already more than a year old, so well worn.

One notable absence from your list are lambdas for example, which are supported by both VC++11 and gcc too.

If you want to move further, then you will have to switch compiler and environment. The effort is significantly greater as you will need to retrain the team (personally I have had some warts with gdb on mingw...).

I would advise cherry picking what works on both compilers, for now, unless you feel adventurous. Migration is always a business risk though.

Refactoring : delegate friendship in sub-functions

Instead of having do_something as function calling other sub-functions, I would suggest you to create an analogous class DoSomehting.

Then you could declare this class as a friend with friend class DoSomehting;. So these sub-functions could be its private methods. The method to call -- could be a public method named e.g. like void DoSomehting::process(Foo& foo):

class Foo
{
friend class DoSomething;
};

class DoSomething
{
public:
void process(Foo& foo)
{
if(case_1) do_1(foo);
else if(case_2) do_2(foo);
else if(case_3) do_3(foo);
//...
}

private:
void do_1(Foo& foo);
void do_2(Foo& foo);
void do_3(Foo& foo);
};

How to port existing C++ code to C++11

Old C++ will work with your C++11 Compiler

  • Reviewing how you use iterators (maybe you can move to range-for)
  • Review if you use function pointer (maybe you can use lamdaes)
  • Review Class Initiators (maybe you can write initialization list)
  • Review your pointer use (maybe you can switch to SmartPtr)
  • Review your use to NULL with pointer maybe you can move to nullptr


Related Topics



Leave a reply



Submit