如何为c ++类(接口)提供属性

时间:2010-05-28 18:27:43

标签: c++ interface multiple-inheritance

我已经构建了几个类(ABC ...),它们对同一个BaseClass执行操作。例如:

struct BaseClass {
    int method1();
    int method2();
    int method3();
}
struct A { int methodA(BaseClass& bc) { return bc.method1(); } }
struct B { int methodB(BaseClass& bc) { return bc.method2()+bc.method1(); } }
struct C { int methodC(BaseClass& bc) { return bc.method3()+bc.method2(); } }

但正如您所看到的,每个班级ABC ...仅使用BaseClass的可用方法的一部分而且我会喜欢将BaseClass拆分成几个块,以便清楚它使用什么和不使用什么。例如,解决方案可以是使用多重继承:

// A uses only method1()
struct InterfaceA { virtual int method1() = 0; }
struct A { int methodA(InterfaceA&); }

// B uses method1() and method2()
struct InterfaceB { virtual int method1() = 0; virtual int method2() = 0; }
struct B { int methodB(InterfaceB&); }

// C uses method2() and method3()
struct InterfaceC { virtual int method2() = 0; virtual int method3() = 0; }
struct C { int methodC(InterfaceC&); }

问题是每次添加新类型的操作时,我都需要更改BaseClass的实现。例如:

// D uses method1() and method3()
struct InterfaceD { virtual int method1() = 0; virtual int method3() = 0; }
struct D { int methodD(InterfaceD&); }

struct BaseClass : public InterfaceA, public InterfaceB, public InterfaceC
// here I need to modify the existing code to add class D
{ ... }

你知道我能干这么干净吗?

感谢您的帮助

编辑:

我忘了提到它也可以用模板完成。但我不喜欢这个解决方案,因为所需的接口没有在代码中明确显示。您必须尝试编译代码以验证是否正确实现了所有必需的方法。另外,它需要实例化不同版本的类(每个BaseClass类型模板参数一个),这并不总是可行也不需要。

3 个答案:

答案 0 :(得分:0)

我认为没有使用其基类的某些元素的派生类没有错。

派生类不需要也不应该使用可用的所有

因此,我认为你的原始实现并没有错,也没有必要重构它。

答案 1 :(得分:0)

methodA,methodB,...的调用者应该知道实际使用了哪些方法1,2,3?

如果他们这样做,你可以在3个不同的接口中拆分BaseClass,并准确添加方法1,2和3所需的接口参数,如下所示:

class Interface1 {virtual int method1() = 0;};
class Interface2 {virtual int method2() = 0;};
class Interface3 {virtual int method3() = 0;};

class A
   {
   int methodA(Interface1 &i1)
      {
      return i1.method1();
      }
   };

class B
   {
   int methodB(Interface1 &i1, Interface2 &i2)
      {
      return i1.method1() + i2.method2();
      }
   };

class C
   {
   int methodC(Interface2 &i2, Interface3 &i3)
      {
      return i2.method2() + i3.method3();
      }
   };

调用者仍然可以选择从多个接口继承,如下所示:

class MyClass : public Interface2, public Interface3
   {
   int method2() {...}
   int method3() {...}
   };
...
MyClass myClass;
C c;
c.methodC(myClass,myClass);

答案 2 :(得分:0)

使用模式Adapter

struct InterfaceA { virtual int method1() = 0; }

struct A { int methodA(InterfaceA& bc) { return bc.method1(); } }

struct BaseClassAdapterForA: public InterfaceA 
{ 
   BaseClassAdapterForA(BaseClass& _bc) : bc(_bc) {}
   virtual int method1() 
   { 
       //note that the name of BaseClass method 
       //can be anything else
        return bc.method1(); 
        // or return bc.whatever();
   }
private:
   BaseClass& bc;
};
//usage
BaseClass bc;
A a;
BaseClassAdapterForA bca(bc);
a.methodA(bca);