Как я могу поделиться логикой, которая специфична для двух классов? - PullRequest
0 голосов
/ 07 октября 2019

У меня есть следующие классы: WidgetBase, TextWidget, ObjectWidget, OtherWidget. TextWidget, OtherWidget и ObjectWidget наследуют WidgetBase. ObjectWidget имеет некоторую логику, которую также должен иметь TextWidget.

class WidgetBase
{
    // some base logic
}

class ObjectWidget : public WidgetBase
{
    // some logic specific for ObjectWidget and TextWidget
}

class TextWidget : public WidgetBase
{
    // some logic specific for ObjectWidget and TextWidget
}

class OtherWidget : public WidgetBase
{
    // this class should not have logic that is specific for ObjectWidget and TextWidget
}

Как я могу поделиться логикой, специфичной для ObjectWidget и TextWidget? Но также, TextWidget может не иметь этой логики. Декораторы и рекурсивные шаблоны здесь, к сожалению, не подходят.

Ответы [ 3 ]

0 голосов
/ 07 октября 2019

Один способ создать класс с такой общей логикой, которая наследуется от WidgetBase. Тогда и ObjectWidget, и TextWidget наследуются от этого класса вместо прямого наследования от WidgetBase.

Если вы не хотите, чтобы ObjectWidget и TextWidget имели общего предка, кроме WidgetBase, вы можете использовать шаблон CRTP . Для этого вы создаете шаблонный класс с общей логикой. Затем ObjectWidget и TextWidget наследуются от WidgetBase и этого класса шаблона (с параметром шаблона, являющимся производным классом).

В качестве альтернативы класс шаблона может наследоваться от WidgetBase, и тогда ObjectWidget и TextWidget нужно только наследовать от класса шаблона.

0 голосов
/ 07 октября 2019

Не уверен, что вы подразумеваете под "логикой" в своем запросе, но вы можете использовать Bridge Design Pattern в качестве решения, подобного этому:

struct impl {
    //implementations here
    void foo() { /* … */ }
    void bar() { /* … */ }
};

class ObjectWidget : public WidgetBase
{
    // some logic specific for ObjectWidget and TextWidget
    public: void foo() { impl_->foo(); }    
    private: struct impl* impl_;
};

class TextWidget : public WidgetBase
{
    // some logic specific for ObjectWidget and TextWidget
    public: void bar() { impl_->bar(); }
    private: struct impl* impl_;
};

class OtherWidget : public WidgetBase
{
    // no access to struct impl    
}
0 голосов
/ 07 октября 2019

Простое наследование должно помочь вам - представьте общую базу утилит (при условии, что у промежуточного пользователя должны быть реквизиты Basewidget) для ObjWidget и TextWidget. Уточнить, если это не подходит #

class WidgetBase
{
    // some base logic
}

class ObjTextCommonLogic 
{
    public:
    // Implement common logic method here
}
class ObjectWidget : public WidgetBase, protected ObjTextCommonLogic
{
    // some logic specific for ObjectWidget and TextWidget
}

class TextWidget : public WidgetBase, protected ObjTextCommonLogic
{
    // some logic specific for ObjectWidget and TextWidget
}

class OtherWidget : public WidgetBase
{
    // this class should not have logic that is specific for ObjectWidget and TextWidget

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...