动态绑定还是开关/案例?

kin*_*kai 1 c c++ design-patterns switch-statement

像这样的场景:
我有不同的对象执行与各自func()实现的类似操作.
func_manager()有两种解决方案可以根据不同的对象调用func()

解决方案1:使用c ++中指定的虚函数字符.func_manager以不同的方式对不同的对象点传入进行工作.

class Object{
  virtual void func() = 0;
}
class Object_A : public Object{
  void func() {};
}
class Object_B : public Object{
  void func() {};
}
void func_manager(Object* a)
{
   a->func();
}
Run Code Online (Sandbox Code Playgroud)

解决方案2:使用普通开关/外壳.func_manager的工作原理与不同类型的传入不同

typedef enum _type_t
{
  TYPE_A,
  TYPE_B
}type_t;

void func_by_a()
{
// do as func() in Object_A
}
void func_by_b()
{
// do as func() in Object_A
}
void func_manager(type_t type)
{
    switch(type){
        case TYPE_A:
            func_by_a();
            break;
        case TYPE_B:
            func_by_b();
        default:
            break;
    }
}
Run Code Online (Sandbox Code Playgroud)

我的问题是2:
1.在设计模式的观点,哪一个更好?
2.在RUNTIME EFFCIENCE的观点,哪一个更好?特别是当对象的种类增加时,总共可能达到10-15,哪一个的开销超过另一个?我不知道switch/case如何实现内部,只是一堆if/else?

非常感谢!

sbi*_*sbi 7

从设计模式的角度来看哪一个更好?

使用多态(解决方案1)更好.
只有一个数据点:想象一下,你有一个围绕两者中的任何一个构建的庞大系统,然后突然需要添加另一种类型.使用解决方案一,您可以添加一个派生类,确保它在需要的地方实例化,然后就完成了.使用解决方案2,您可以在整个系统中覆盖数以千计的switch语句,并且或多或少无法保证找到所有必须为新类型修改它们的位置.

从RUNTIME EFFCIENCE的观点来看,哪个更好?特别是对象的种类

这很难说.
我记得Stanley Lippmann的Inside the C++ Object Model中的一个脚注,他说研究表明,虚拟函数可能对切换类型有一个小优势.然而,我会很难引用一章和一节,并且,IIRC,优势似乎不足以使决定依赖于它.

  • @sbi,@Michael Aaron Safyan。关于“开关”——一团糟。他不是将所有这些混乱封装在管理功能中吗?看起来并没有比 OO 封装差那么可怕 (2认同)