避免公共类中的代码重复
Posted
技术标签:
【中文标题】避免公共类中的代码重复【英文标题】:Avoiding duplication of code in common classes 【发布时间】:2012-03-13 18:44:44 【问题描述】:我有一个回调函数,叫做
MyCallBack(int type)
我有 3 个类 B、C 和 D 从 A 派生,具有通用方法名称 目前我的代码是这样的
MyCallBack(int type)
if(type == 1 )
B b;
b.perform();
else if(type==2)
C c;
c.perform();
else if(type ==3)
D d;
d.perform();
有没有办法可以减少这段代码,比如
MyCallBack(int type)
Common object(type);
object.perform();
【问题讨论】:
【参考方案1】:基本上,您需要的是多态性。
你所有的类B
,C
,D
都应该派生自一个抽象类说SuperBase
和一个纯虚方法perform()
。
您的代码应仅使用指向 SuperBase
的指针,其中包含实际具体类对象的地址。
一旦你有了这个,根据被指向对象的实际类型,来自适当类的方法将被调用。
这种方法的优点是没有硬编码类型检查以及使用Open Closed principle 的松散耦合设计的灵活性。
【讨论】:
【参考方案2】:@Als 使用多态的想法是一个很好的想法 (IMO),但它只有在您将输入整数转换为实际类型之后 才真正起作用。一种方法是索引一个指向对象的指针数组:
MyCallback(int type)
static A *ptrs[] = new B, new C, new D;
ptrs[type-1]->perform();
编辑:以防万一您不知道,为了使其正常工作,perform
需要是在A
中声明的(可能是纯的)虚函数,并在每个B
中定义, C
和 D
。您需要确保函数的整个签名,而不仅仅是名称,在类之间是相同的。
【讨论】:
【参考方案3】:interface 怎么样?
class A
public:
virtual void perform() = 0;
;
class B : public A
public:
void perform() ...
;
// Same for C, and D
所以你的回调看起来像:
MyCallBack(A& performer)
performer.perform();
如果不能更改回调的签名,那abstract factory pattern:
function A* AFactory(int type)
switch(type)
case 1: return new B(); // Assuming B, C, D all derive from A
case 2: return new C();
case 3: return new D();
default: return nullptr; // nullptr is a c++11 thing. Use NULL, if you're still on C++03
然后是回调...
MyCallBack(int type)
std::unique_ptr<A> obj(AFactory(type)); // this will automatically release the memory once it falls out of scope
obj->perform();
【讨论】:
不应该是MyCallBack(A& performer)
通过一个指针(即MyCallBack(A* performer)
)然后用performer->perform()
调用它吗?
通过引用基类来引用派生类是合法的。当然,如果传入的是 A*,那么他必须使用 A*。在可能的情况下,人们应该更喜欢对指针的引用。【参考方案4】:
您应该创建对象工厂或只是静态(全局)方法返回指向基类型的指针(或引用,可能),但包含派生类型的对象。
CBase* CreateObjectBasedOnType(int type)
// check for type and return appriopriate derived object
MyCallBack(int type)
CreateObjectBasedOnType(type)->perform();
请注意,您要调用的方法应该是虚拟的。
更好的方法可以使用模板
template<typename T>
MyCallBack()
T Obj;
Obj.perform();
【讨论】:
以上是关于避免公共类中的代码重复的主要内容,如果未能解决你的问题,请参考以下文章