views:

121

answers:

4

I am migrating some C++ code from structures to classes.

I was using structures mainly for bit-field optimizations which I do not need any more (I am more worried about speed than saving space now).

  • What are the general guidelines for doing this migration? I am still in the planning stage as this is a very big move affecting a major part of the code. I want to plan everything first before doing it. What are all the essential things I should keep in mind?
+1  A: 

There is no meaningful difference between structures and classes in C++ (they differ only by default visibility). I wouldn't bother to migrate the structures to classes unless you are going to add meaningful behaviors as well.

Brent Arias
@Mystagogue: adding "meaningful behaviours" is part of the plan.
Lazer
@eSKay: Might not be important for you, but: In C, an empty structure has size 0. In C++, an empty structure/class has size 1.
jweyrich
@jweyrich: Whoa!! [C](http://codepad.org/XKyHtIZN#output) vs [C++](http://codepad.org/kI0V6Xjw#output)! Never know this. Never had to use an empty structure. thanks for pointing out! Found some explanations [here](http://stackoverflow.com/questions/621616).
Lazer
+4  A: 

I can't name all the essential things, but I can name one: encapsulation.

The only technical difference in C++ between struct and class is the default access. In a struct, everything is public by default; in a class, everything is private. I'm assuming that you're talking about POD structs here, where everything is public.

What I would do is this:

  1. Change the struct keyword to class and see where calling code breaks. That would give you a clue about what parts of the type are used where.
  2. From that, determine which elements of the type should be public, which should be private.
  3. Write accessor functions for the public parts, and change calling code to use them.
  4. Move the code that needs access to private parts into the class itself.
Thomas
@Thomas: thanks!
Lazer
+3  A: 

When updating a legacy codebase from C to C++, my experience is there is very little value and entirely too much effort involved in actually rearchitecting your application to convert structures to traditional C++ objects. Because make no mistake, thats is what you will end up doing. It won't seem it at first, but eventually you'll realize you're redesigning the application.

You don't say enough about what your goals are, so maybe this is your goal, but if you're just trying to convert to C++ so new code in your app can be C++, just rename the files, add a bunch of casts where implicit conversions from void* were occurring before, and move on with your life.

Terry Mahaffey
+1  A: 

First, I will join the others and say that moving all the code from structures to classes may not be the best move. If you were to do it well (that is, more than just changing struct X { with class X { public:) that means redesigning the application (more or less a complete rewrite).

This involves introducing new bugs, new development cycles, extra testing, changing documentation and so on.

Second, considering you may have valid reasons for doing this (for me "just for fun" and "to see if I can do it" can be valid reasons in some situations :D) here are my answers to your questions:

1. What are the general guidelines for doing this migration?
2. What are all the essential things I should keep in mind?

Guidelines and things to keep in mind:

  • work in very small iterations, and make sure the application is functional between iterations. If you have unit-tests defined, you can work your way through them (pick one unit, redesign following a set of steps (see below), then adapt and run the tests.

  • pick one area of your code and finish it.

  • try to follow these steps for each change:

    • analyze functionality and redesign
    • create the new implementation in parallel with the old one
    • switch in the new implementation everywhere the old one is used
    • test that the application still works
    • remove the old code
    • test that the application still works
  • If you're not doing it at the moment, start using a branching source-control software. Nothing less quite cuts it. I recommend Mercurial, but I understand GIT has about the same features. You can thank me later :o).

  • Perform changes transactionally (start with one area and finish it, without adding changes from other areas while the changes for the first one are half-way through). If you use a branching source-control and multiple developers you can have one change/area per developer at a time, then centralize the changes.

Advantages of a refactoring methodology:

  • the application stays functional if you decide half-way through that the effort is not worth it (or if management decides the effort is not worth it)

  • the stability of the application remains manageable through the changes

If you establish some milestones this should be quite manageable.

Good luck!

utnapistim