[英]Polymorphism: is this (potentially intensive) use of static_cast a fatality?
这是上下文: Model
具有(指向) Parameter
和output
。 Model
和Parameter
是抽象类。 我们使用类型的指针Model*
操纵各种衍生(混凝土)班的Model
,它的指针Parameter
动态指向的各种衍生(混凝土)类的实例Parameter
。
以下是类的简化版本。 我知道应该避免使用new
或至少delete
后delete
,但我省略了非主题代码行(例如析构函数)。
// Abstract classes
class Parameter {
public:
virtual void reinitialize() = 0;
};
class Model{
public:
Model(Parameter *argt){ ptr_param = argt; }
virtual void computeModelOutput() = 0;
double output;
Parameter *ptr_param;
};
// Concrete classes
class ACertainKindOfParameter : public Parameter{
public:
ACertainKindOfParameter(int argt){ value = argt; }
virtual void reinitialize(){ value = 1; }
int value;
};
class ACertainKindOfModel : public Model{
public:
ACertainKindOfModel(int argt) : Model(new ACertainKindOfParameter(argt)){}
virtual void computeModelOutput(){
output = 10.0 + (double)(static_cast<ACertainKindOfParameter*>(ptr_param)->value);
}
};
int main(){
ACertainKindOfModel myModel{5};
Model *ptr_model = &myModel;
ptr_model->computeModelOutput();
std::cout << ptr_model->output << std::endl; // 15
}
在这段代码中困扰我的是ACertainKindOfModel
没有直接访问value
,所以我显然需要使用static_cast
。 一个真实的Model
当然会有一个例如50个Parameter
s的向量,而不仅仅是一个,所以每次计算output
(或任何其他依赖于参数的动作)这意味着50 static_cast
。 对我来说这看起来不是一个好习惯,但我可能错了。 你看到设计中有任何缺陷吗?
注意:我想让Parameter
成为一个类模板,但它似乎不是一个有效的选项,因为当考虑不同类型的value
时, Parameter
的方法会有很大差异。 在上面的简单示例中, value
的类型为int
,但在从Parameter
派生的另一个类中,它可以是用户定义的类型,例如,只有三个可能值R
, G
和B
Color
,以及reinitialize()
将与value = 1
。 Parameter
虚拟getter()
会很棒,但也不会工作,因为重定义中的返回类型存在冲突。
有几种方法可以使它更清洁。 如果Model
不需要访问ptr_param
,则可以从Model
删除它并将其存储在每个派生类中,并使用正确的类型。
或者您可以将static_cast
封装在每个模型类中的getter函数中:
ACertainKindOfParameter *getParam() const { return static_cast<ACertainKindOfParameter *>(ptr_param); }
您可以将这两种技术结合起来。 在派生模型类中定义参数,并使用协变返回类型以允许基类Model
类访问。 在Model
,声明一个getter:
virtual Parameter *getParam() const = 0;
然后,在每个模型中,声明一个协变覆盖:
virtual ACertainKindOfParameter *getParam() const override { return ptr_param; }
假设ptr_param在ACertainKindOfModel
声明。 如果不是,您将需要如上所述应用static_cast
。
或者,您可以将static_cast
的结果保存在compute
函数中,以避免多次使用它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.