-1

I'm working on a custom engine where I have 2 different transform classes, one for 2D and one for 3D. I'm using a #define to choose which transform class to use and using that definition instead of the classname in places where the logic should be the same. I am at a part now where I want them to have different logic and wanted to do a comparison to branch off for that. What do I need to do to get this to work?

class Transform2D;
class Transform3D;

#define TransformClass Transform2D

if(TransformClass == Transform2D)
{
  //like this
}
else    
{
  //like that
}

Type id worked for that. How do you handle?

if ( typeid(TransformClass) == typeid(Transform2D) )
{
    ittransform->SetRotation(0);
    ittransform->SetScale(Vector2D(defaultScale, defaultScale));
}
else
{
    ittransform->SetRotation(Vector3f());
    ittransform->SetScale(Vector3f(defaultScale, defaultScale, defaultScale));
}
Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
  • This kind of type checking is usually the indication of a poor architecture/class design. Either use overloaded functions, like Sean suggested, or, define a top level interface class that is implemented by either a transform2D or transform3D – glampert Sep 10 '14 at 22:46
  • Instead of #define just make your function a template that operates on both Transform2D/3D classes using common interface like Sean suggested. – JarkkoL Sep 11 '14 at 01:06

3 Answers3

6

Use function decomposition (break your logic into sub-functions) and then make use of overloading.

void do_something(Transform2D const& t) {
  ...
}

void do_something(Transform3D const& t) {
  ...
}

void test() {
  TransformClass tc = ...
  do_something(tc); // invokes the desired overload
}

Also, use a typedef or type alias instead of a define, e.g.

#if defined(USE_3D)
using TransformClass = Transform3D;
#else
using TransformClass = Transform2D;
#endif

You can also define the alias via std::conditional and be even more functional-y and C++-y.

Sean Middleditch
  • 2,517
  • 18
  • 31
  • Does `using TransformClass = Transform2D;` do the same thing as the #define or does it have more/different behaviour.` – Colin Avrech Sep 10 '14 at 22:51
  • @ColinAvrech: It has _slightly_ different behavior. Namely, if you name a variable `TransformClass`, it's actually called `TransformClass` and not `Transform3D`. A few other differences. – Mooing Duck Sep 10 '14 at 23:51
  • What is the jargon/term for that use? – Colin Avrech Sep 11 '14 at 01:15
  • It's a "type alias" and is similar to a typedef, but the using syntax is easier to read and a bit more powerful (it allows the use of parametrized aliases, aka alias templates). Basically, just use it where you have used a typedef before (I think it's a complete replacement, but maybe there's a corner case I'm unaware of). – Sean Middleditch Sep 11 '14 at 03:53
1

Do not use if() in this situation.

Since you're coding with the pre-processor, stick with it:

# if USING_3D
    3d code
# else
    2d code
# endif

and if you strive to keep most of the methods and ancilliary classes looking broadly the same, you'll probably manage to avoid too much use of #if

Old C code was littered with this stuff, and it was considered good. However nowadays, it's very old fashioned. Think thrice before you continue down this path.

0

I think the easiest option is to create an extra define, something like this:

#define USING_CLASS_2D 1

#if USING_CLASS_2D
#define TransformClass Transform2D
#else
#define TransformClass Transform3D
#endif

if (USING_CLASS_2D)
{
}
else
{
}
Adam
  • 882
  • 5
  • 10
  • 1
    If adopting this approach, then why even use `if()` logic? In this case, the correct would be a preprocessor `#if` or `#ifdef`. – glampert Sep 10 '14 at 22:49
  • Why do this over `typedef`? –  Sep 10 '14 at 23:10
  • I used `#define` and `if`, as that's what was used in the question. You could use a typedef instead. – Adam Sep 10 '14 at 23:20