这是上下文:A Model
有一个(指向)Parameter
和output
。 Model
和Parameter
是抽象类。我们使用Model*
类型的指针来操纵Model
的各种派生(具体)类,其指针Parameter
动态指向各种衍生(具体)类Parameter
的实例。多态性:这是(可能密集型)使用static_cast致命吗?
下面是一个简化版本的类作为例子。我知道new
应该避免或至少后跟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
当然会具有例如每次计算output
(或任何其他依赖于参数的动作)时,这将意味着50 static_cast
。这对我来说不太好,但我可能是错的。你看到设计中的缺陷吗?
注:我觉得做Parameter
类模板,但它似乎并没有一个有效的选择,因为Parameter
的方法时,不同类型的value
被认为是深有所不同。在上面的简单示例中,value
类型为int
,但是在从Parameter
派生的另一类中,它可以是用户定义的类型,例如, Color
只有三个可能的值R
,G
和B
和reinitialize()
会与value = 1
有很大不同。 Parameter
中的虚拟getter()
会很好,但是也不起作用,因为重定义中的返回类型是冲突的。
你打算怎么处理价值?如果是计算,请查看[访问者模式](https://en.wikipedia。org/wiki/Visitor_pattern),所以没有其他类必须知道它的价值。如果是显示,可以考虑添加一个虚拟getter,它以'string'的形式返回中性形式的值。 – user4581301
@ user4581301事实上,'value'主要用于计算,如我写的那段代码所示,也可能出现在if(value == R)等条件中,等等(特别是value是不是数字)。感谢您对Visitor模式的建议。 – Georg
*“我知道应该避免新的”*。所以使用智能指针:甚至更少的代码行。 – Jarod42