繁体   English   中英

多态性:这是(可能是密集的)使用static_cast致死的吗?

[英]Polymorphism: is this (potentially intensive) use of static_cast a fatality?

这是上下文: Model具有(指向) Parameteroutput ModelParameter是抽象类。 我们使用类型的指针Model*操纵各种衍生(混凝土)班的Model ,它的指针Parameter动态指向的各种衍生(混凝土)类的实例Parameter

以下是类的简化版本。 我知道应该避免使用new或至少deletedelete ,但我省略了非主题代码行(例如析构函数)。

// 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派生的另一个类中,它可以是用户定义的类型,例如,只有三个可能值RGB 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM