首页 > 解决方案 > 有没有比在所有派生类都没有实现的基础上添加新的虚函数更好的设计实践

问题描述

我有如下所示的类层次结构。这是实际代码的简化版本。

class Base
{
public :
   // user_define_type is a output parameter
   virtual void Fill(user_define_type);
}

class A : public Base
{
public :
    void Fill(user_define_type) override;
}
class B : public Base
{
public :
    void Fill(user_define_type) override;
}

我正在重写Fill()方法,因为我需要在两个派生类中使用不同的格式。现在我必须再写一个派生自“Base”的类,因为它具有通用功能。现在我的问题是必须实现新类,该类将Fill()在不同的用户定义类型上运行。由于我要从工厂返回基类指针,所以 new在基类Fill()中必须是虚拟的,但这意味着我必须在旧类“A”和“B”中添加它的定义,并从它们那里抛出不支持的异常。这不是一个好的设计。大家有什么更好的设计可以推荐吗?提前致谢。

标签: c++classclass-design

解决方案


我相信您需要为您的 user_defined_types 创建一个通用基类才能实现此目的。我也认为这可能是使用策略模式的好地方。

基本上,您创建

class user_defined_type_base 
{
    ...
}

class user_defined_type_derived : public user_defined_type_base
{
    ...
}

class DoSomething
{
    private:
        DoSomethingStrategy *strategy;

    public:
        DoSomething(DoSomethingStrategy *strategy) { this->strategy = strategy; }
        void Fill(user_defined_type_base *type) { this->strategy->Fill(type); }
}

class DoSomethingStrategy
{
    public:
        virtual void Fill(user_defined_type_base *obj) = 0;
}

class DoSomethingStrategyA : public DoSomethingStrategy
{
    public:
        void Fill(user_defined_type_base *obj)
        {
            ...
        }
}

class DoSomethingStrategyB : public DoSomethingStrategy
{
    public:
        void Fill(user_defined_type_base *obj)
        {
            ...
        }
}

class DoSomethingStrategyC : public DoSomethingStrategy
{
    public:
        void Fill(user_defined_type_base *obj)
        {
            ...
        }
}

void main()
{
    DoSomethingStrategy *strategy = new DoSomethingStragegyA();
    DoSomething *dosomething = new DoSomething(strategy);
    user_defined_type_base *type = new user_defined_type_base();
    dosomething->Fill(type);

    DoSomethingStrategy *strategyC = new DoSomethingStragegyC();
    DoSomething *dosomethingC = new DoSomething(strategyC);
    user_defined_type_base *typeC = new user_defined_type_derived();
    dosomethingC->Fill(typeC);
}

推荐阅读