多态实例返回多态实例

Polymorphic instance returning polymorphic instance

本文关键字:多态 实例 返回      更新时间:2023-10-16

类是从一个父母继承的设计,其多态性方法返回也是多态实例是由于dynamic_cast而设计的不良设计?

以下是一个例子。

#include <iostream>
class Data{
public:
virtual void doSomething(){}
};
class DataB:public Data{};
class DataC:public Data{};
class ClassA{
public:
  virtual Data* func() = 0;
};
class ClassB:public ClassA{
public:
  DataB* func(){
    return new DataB();
  }
};
class ClassC:public ClassA{
public:
  DataC* func(){
    return new DataC();
  }
};
int main(){
  ClassA * obj = new ClassB();
  Data * data = obj->func();
  DataB* data_b = dynamic_cast<DataB*>(data);
  if(data_b){
    std::cout<<"This is DataB"<<std::endl;
  }else{
    DataC * data_c = dynamic_cast<DataC*>(data);
    if(data_c){
      std::cout<<"This is DataC"<<std::endl;
    }
  }
  return 0;
}

要找出实例生成的,需要dynamic_cast

,但许多人说dynamic_cast不需要。

出于这个原因,是错误的设计吗?

dynamic_cast如果参数不转换为所需类,则将返回null。此方法的问题是,如果有多个继承级别,则可以返回有效指针的中间孩子的动态cast。

设计很糟糕,因为从多态性意识形态的POV中,最好针对基类已经声明的虚拟方法实施额外的功能。另一种方法是实现某种类型的识别方法,被儿童覆盖,您仍然需要Dynamic_cast,但仅尝试一次尝试。

在true/pure对象的设计"界面设计"中是关键。也就是说,在不知道基本的派生类别的情况下,应使用基类指针的每个地方。

您的代码显示了众所周知的"设计模式 - 抽象工厂",其中指出:抽象工厂提供了一个界面,用于创建相关对象的家庭,而无需指定其具体类别。

弄清楚需要从中生成实例,需要Dynamic_cast。 这取决于产品/系统的要求。在一段时间内,需要生成/更改,并且很难维护"通过接口设计"的密钥,因此被迫使用dynamic_cast。另外,在工作流程中,如果您真的想在派生类中使用某些东西(不是多态),那么将需要dynamic_cast,实际上并不是说'嘿!您的设计很糟糕。

,但许多人说不需要Dynamic_cast。对象最小或使用dynamic_cast几乎为零。

带有此原因,是错误的设计吗? 这取决于我们产品/系统的当前阶段。如果您是新鲜的产品设计,那么如果使用dynamic_cast,则需要重新考虑设计。如果产品/系统是旧的或有太多的旧代码,则可以使用dynamic_cast Inorder来解决问题。

精心设计的OOP程序不应求助于使用类似于黑客的铸造。我已经更改了您的代码段,避免了动态铸造。避免使用datab*和datac*,因为抽象基类数据*可以处理它,并且ClassB和ClassC中的成员函数将更加均匀。

#include <iostream>
class Data{
public:
virtual void doSomething(){}
};
class DataB:public Data{};
class DataC:public Data{};
class ClassA{
public:
  virtual Data* func() = 0;
};
class ClassB:public ClassA{
public:
  Data* func(){
    return (DataB*) (new DataB());
  }
};
class ClassC:public ClassA{
public:
  Data* func(){
    return (DataC*) (new DataC());
  }
};
int main(){
  ClassA * obj = new ClassB();
  Data * data = obj->func();
  Data* data_b = data;
  if(data_b){
    std::cout<<"This is DataB"<<std::endl;
  }else{
    Data * data_c = data;
    if(data_c){
      std::cout<<"This is DataC"<<std::endl;
    }
  }
  return 0;
}