Now I have a lot of airplanes, in the ideal world
the interface of the airplanes(or anything) should be unify
but for some kind of weird reasons, the class for different airplanes
are designed like this

struct airplane_A
{
  fly_A();
  speed_up_A();
  //blah blah blah
};

struct airplane_B
{
  fly_B();
  speed_up_B();
  //blah blah blah
};

Actually, the interfaces could be unified, but what is done is done.
There are already more than 30 airplanes are designed like this
If the interfaces of these airplanes are unify
We don't need to write a lot of redundancy codes
It could be solved by template or virtual
But now I don't have a good way to solve this kind of problem
except of writing a simple program to generate codes for me.
I try to use wrapper to wrap those interfaces, but it is impractical
since I have to design many wrappers for different airplane(macro is hard to debug)

This design just like

vector<int> A;
vector<double> B;
A.push_back_int(3);
B.push_back_double(4.0);
//etc

I don't know how to fix it, really

Thanks for your help

Recommended Answers

All 3 Replies

A template class won't quite do it because the 'fly' and 'speed up' functions have different names in each struct... you can't write a single template that knows how to call the different methods of each airplane; you'd need a common interface for the airplanes, your lack of which is the original problem.

So. If you don't have any control over the original structures, then I think you're on the right track with creating an interface and a bunch of wrappers. You don't need a macro if you don't mind defining the classes by hand. Since we don't have your code here, I don't know if this is anything like what you tried, so here's an example in case it's useful:

#include <iostream>

using namespace std;

struct airplane_A
{
    void fly_A() { cout << "Airplane A FLY!" << endl; }
    void speed_up_A() { cout << "Airplane A SPEED!" << endl; }
};

struct airplane_B
{
    void fly_B() { cout << "Airplane B FLY!" << endl; }
    void speed_up_B() { cout << "Airplane B SPEED!" << endl; }
};

class Airplane
{
public:
    virtual void fly() = 0;
    virtual void speedUp() = 0;
};

class AirplaneA : public Airplane
{
public:
    void fly() { plane.fly_A(); }
    void speedUp() { plane.speed_up_A(); }

private:
    airplane_A plane;
};

class AirplaneB : public Airplane
{
public:
    void fly() { plane.fly_B(); }
    void speedUp() { plane.speed_up_B(); }

private:
    airplane_B plane;
};

void testPlane(Airplane* p)
{
    p->fly();
    p->speedUp();
}

int main()
{
    Airplane* a = new AirplaneA();
    Airplane* b = new AirplaneB();

    testPlane(a);
    testPlane(b);
}

Macros would make it shorter, but if you want clarity, I'd just write the wrappers individually. That also allows you to deal with greater variation in how the individual airplane structs are implemented.

A macro example, for anyone who cares:

#include <iostream>

using namespace std;

struct airplane_A
{
    void fly_A() { cout << "Airplane A FLY!" << endl; }
    void speed_up_A() { cout << "Airplane A SPEED!" << endl; }
};

struct airplane_B
{
    void fly_B() { cout << "Airplane B FLY!" << endl; }
    void speed_up_B() { cout << "Airplane B SPEED!" << endl; }
};

class Airplane
{
public:
    virtual void fly() = 0;
    virtual void speedUp() = 0;
};

#define AIRPLANE(suffix) \
class Airplane##suffix : public Airplane \
{ \
public: \
    void fly() { plane.fly_##suffix(); } \
    void speedUp() { plane.speed_up_##suffix(); } \
private: \
    airplane_##suffix plane; \
}

AIRPLANE(A);
AIRPLANE(B);

void testPlane(Airplane* p)
{
    p->fly();
    p->speedUp();
}

int main()
{
    Airplane* a = new AirplaneA();
    Airplane* b = new AirplaneB();

    testPlane(a);
    testPlane(b);
}

In a similar fashion as gusano79 has suggested, you can use a templated wrapper to reduce the amount of coding necessary for the different wrappers.

Here is what I mean:

class Airplane {
  public:
    virtual void fly() = 0;
    virtual void speed_up() = 0;
};

template <typename AirplaneType, 
          void (AirplaneType::*FlyFunction)(),
          void (AirplaneType::*SpeedUpFunction)()>
class AirplaneWrapper : public Airplane {
  public:
    virtual void fly() {
      plane.*FlyFunction();
    };
    virtual void speed_up() {
      plane.*SpeedUpFunction();
    };
  private:
    AirplaneType plane;
};


typedef AirplaneWrapper<AirplaneA,&AirplaneA::fly_A,&AirplaneA::speed_up_A> IAirplaneA;

typedef AirplaneWrapper<AirplaneB,&AirplaneB::fly_B,&AirplaneB::speed_up_B> IAirplaneB;

//... you can even generate this with a MACRO if feasible.

Thanks for your help
Especially the second example, I never though that I could use that kind of
technique to generate wrappers for me.
I would try to make a good use of it.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.