我已经构建了几个类(A
,B
,C
...),它们对同一个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(); } }
但正如您所看到的,每个班级A
,B
,C
...仅使用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类型模板参数一个),这并不总是可行也不需要。
答案 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);