C++ 如何避免C++;特定类方法的强制转换?设计模式?

C++ 如何避免C++;特定类方法的强制转换?设计模式?,c++,inheritance,casting,design-patterns,C++,Inheritance,Casting,Design Patterns,假设我有这样的东西: class Father { public: virtual int genericMethod (void) =0; }; class Son1: public Father { public: int genericMethod () { } }; class Son2: public Father { public: int genericMethod () { } int spe

假设我有这样的东西:

class Father {
    public:
      virtual int genericMethod (void) =0;
  };

class Son1: public Father {
  public:
    int genericMethod ()
      { }
  };

class Son2: public Father {
  public:
    int genericMethod ()
      { }
    int specifClassMethod()
      { }
  };
我主要做以下几点:

Father * test = new Son2();

test->specifClassMethod(); //Can't do this! It is specific of Class Son2 and is not a virtual method in class Father!
Father * test = new Son1();
SpecificInterface * specificAPI = test->getSpecificInterface();
if( specificAPI )
  specificAPI->specifClassCmethod();
这里的主要问题是了解通过父接口访问Son2特定方法的更好方法。我想知道是否有一种设计模式可以解决这个问题或其他问题。我不想做演员,也不想在我的代码中加入很多“如果”

问候,


Eduardo

否。要调用仅存在于子类中的方法,必须强制转换到child类


虽然您可以创建一个映射,将函数名映射到函数,但可以从子类的构造函数中将函数添加到映射中,然后使用类似于
test->callMethod(“name”)您必须使所有这些方法具有相同的签名,或者使用varargs来传递参数,这不是很好。

否。要调用仅存在于子类中的方法,您必须强制转换到child类


虽然您可以创建一个映射,将函数名映射到函数,但可以从子类的构造函数中将函数添加到映射中,然后使用类似于
test->callMethod(“name”)
您必须使所有这些方法具有相同的签名,或者使用varargs来传递参数,这不是很好。

您可以
static_cast(test)->specifyClassCmethod()但只有当父*测试=新Son2()时,这才有效

您可以
静态转换(测试)->指定ClassCmethod()但只有当父*测试=新Son2()时,这才有效

如果您确实有一些特定于
Son2
的内容,那么您应该使用
动态播放。如果可以使用默认的空行为将其作为虚拟函数添加到基类中,那么您可以不用强制转换来解决问题(但这并不是您在问题中所说的那样)

解决问题的一种设计模式是使用。该对象将具有所有易于调用的方法,并将它们委托给真实对象或不委托给真实对象

代理模式的优点:

  • 您可以集中将后面的对象区分到一个位置所需的逻辑
  • 您可以轻松添加一些日志记录
  • 客户端代码保持简单,
    Son
    类清除了多余的内容

如果您确实有特定于
Son2
的内容,那么您应该使用
dynamic\u cast
。如果可以使用默认的空行为将其作为虚拟函数添加到基类中,那么您可以不用强制转换来解决问题(但这并不是您在问题中所说的那样)

解决问题的一种设计模式是使用。该对象将具有所有易于调用的方法,并将它们委托给真实对象或不委托给真实对象

代理模式的优点:

  • 您可以集中将后面的对象区分到一个位置所需的逻辑
  • 您可以轻松添加一些日志记录
  • 客户端代码保持简单,
    Son
    类清除了多余的内容

    • 您也不能通过强制转换合法地解决这个问题,因为“test”指向的是父对象,而不是Son2对象。强制转换对象类型意味着“相信我,编译器,这个变量实际上包含X”。它不会以某种方式神奇地将基础对象转换为派生对象;它只会告诉编译器一些你已经知道它不知道的东西


      如果您希望行为因派生类而异,则将该行为移动到虚拟方法中——即,希望调用specificCLassMethod()的代码属于父类的虚拟方法。

      您也无法通过强制转换合法解决此问题,因为“test”指向的是父对象,而不是Son2对象。强制转换对象类型意味着“相信我,编译器,这个变量实际上包含X”。它不会以某种方式神奇地将基础对象转换为派生对象;它只会告诉编译器一些你已经知道它不知道的东西


      如果希望行为因派生类而异,则将该行为移动到虚拟方法中——即,希望调用specificCLassMethod()的代码属于父类的虚拟方法。

      可能访问者模式就是您要寻找的模式


      也许访问者模式就是您要寻找的模式


      首先,您不能为类“父”创建实例,因为它是一个抽象类(具有虚int-genericMethod(void)=0;-纯虚函数)。相反,可以为它分配一个实例


      首先,您不能为类“父”创建实例,因为它是一个抽象类(具有虚拟int-genericMethod(void)=0;-纯虚拟函数)。相反,可以为其分配一个实例


      可能的方法是使用带有可选方法的特定接口,以及在基类(可能返回零)中获取此接口的虚拟方法:

      用途如下:

      Father * test = new Son2();
      
      test->specifClassMethod(); //Can't do this! It is specific of Class Son2 and is not a virtual method in class Father!
      
      Father * test = new Son1();
      SpecificInterface * specificAPI = test->getSpecificInterface();
      if( specificAPI )
        specificAPI->specifClassCmethod();
      

      可能的方法是使用带有可选方法的特定接口,以及在基类(可能返回零)中获取此接口的虚拟方法:

      用途如下:

      Father * test = new Son2();
      
      test->specifClassMethod(); //Can't do this! It is specific of Class Son2 and is not a virtual method in class Father!
      
      Father * test = new Son1();
      SpecificInterface * specificAPI = test->getSpecificInterface();
      if( specificAPI )
        specificAPI->specifClassCmethod();
      

      你的例子有点做作,有可能让它更具体吗?为了比@Coda更明确,你正在使用的实际设计是什么,这样我们可以指出其中的缺陷?如果你的设计还可以,那么
      dynamic\u cast
      就是你的朋友。通常,使用
      dynamic\u cast
      是嗅到代码的标志。不要忘记向基类添加虚拟析构函数。否则删除“父*test=…;删除test;”将不会调用正确的析构函数。您的示例有点做作,是否有可能使其更具体?为了比@Coda更明确,您使用的实际设计是什么,以便我们指出其中的缺陷?如果你的设计还可以,那么
      dynamic\u cast
      就是你的朋友。通常,usi