Управление с указателями на производный класс возражает через указатели на объекты базового класса

Вместо кода вы можете отключить вариант на странице редактирования продукта. На вкладке вариантов в мета-полях данных продукта вы можете снять флажок включения. Это удалит выпадающий список из передней части. Скриншот прилагается к тому же.

включить / отключить изменение продукта

5
задан chester89 22 April 2009 в 07:58
поделиться

4 ответа

Решением для доступа к более производным элементам класса из базового класса является шаблон посетителя.

class BaseBankAccount {
public:
    ...
    virtual void AcceptVisitor(IVisitor& v) = 0;
};


class AccountTypeA : public BaseBankAccount {
public:
   void TypeAFeature() {...}

   void AcceptVisitor(IVisitor& v)
   {
       v.VisitAccountTypeA(*this);
   }
};

class AccountTypeB : public BaseBankAccount {
public:
   void TypeBFeature() {...}

   void AcceptVisitor(IVisitor& v)
   {
       v.VisitAccountTypeB(*this);
   }
};

class IVisitor {
public:
    virtual void VisitAccountTypeA(AccountTypeA& account) = 0;
    virtual void VisitAccountTypeB(AccountTypeB& account) = 0;
};

class ConcreteVisitor : public IVisitor{
public:
    void VisitAccountTypeA(AccountTypeA& account) 
    {
         account.TypeAFeature(); //Can call TypeA features
    }

    void VisitAccountTypeB(AccountTypeB& account) 
    {
         account.TypeBFeature(); //Can call TypeB Features
    }
};

Взаимодействие не сразу очевидно. Вы определяете чистый виртуальный метод AcceptVisitor в своем базовом классе, который принимает Объект типа IVisitor в качестве параметра. IVisitor имеет один метод на производный класс в иерархии. Каждый производный класс по-разному реализует AcceptVisitor и вызывает метод, соответствующий его конкретному типу (AccountTypeA & AccountTypeB), и передает конкретную ссылку на сам метод. Вы реализуете функциональность, которая использует более производные типы иерархии в объектах, производных от IVisitor. Википедия: Шаблон посетителя

7
ответ дан 14 December 2019 в 01:16
поделиться

. C ++ делает ограничение на общедоступный интерфейс базового класса (и, кстати, разве в том, что вы опубликовали, не хватает «виртуального»)? Если вам нужен доступ к определенным функциям, которые принадлежат только производному классу, то вам нужно привести указатель на этот класс с помощью dynamic_cast.

Если вы обнаружите, что нужно использовать dynamic_cast много, то ваш дизайн, возможно, не нужен, но это очень трудно комментировать, не зная точных деталей бизнес-сферы, с которой вы имеете дело.

Одним из возможных способов решения этой проблемы является предоставление методов доступа к компонентам учетной записи. Например, метод базового класса GetPortfolio () может вернуть указатель на объект Portfolio, но только для классов учетных записей, которые имеют Portfolios. Для других классов вы определяете их метод GetPortfolio () как возвращающий NULL. Когда у вас есть указатель Портфолио, вы работаете с интерфейсом портфеля (который сам по себе может представлять иерархию классов), а не с BankAccount.

1
ответ дан 14 December 2019 в 01:16
поделиться

Необходимость опускания, хотя и всегда рискованная, иногда неизбежна. Например, до того, как шаблоны были введены в Java, вам приходилось все время принижать при использовании стандартных коллекций, поскольку они работали только с объектами.

Я предполагаю, что когда вы понижаете, вы делаете его безопасным с помощью dynamic_cast. Я также предполагаю, что в вашем базовом классе все виртуально, и вы просто опустите его в этом коде.

В частности, на ваш вопрос нет единого правильного ответа. Вообще говоря, когда вы собираете кучу производных классов в гетерогенную коллекцию, вы либо используете коллекцию как «битовую корзину», либо намереваетесь работать с наименьшим общим знаменателем (интерфейсом базового класса).

Если дело в первом случае, то может быть необходимым уныние, хотя и некрасивое. Если это последний случай, то вам нужно спросить себя, почему вы хотите обрабатывать определенные подтипы по-разному и можете ли вы изменить реализацию базового класса, чтобы каким-либо образом вызывать соответствующие вещи в производном классе (например, через производный метод).

В любом случае вы можете пересмотреть вопрос о том, имеет ли гетерогенная коллекция смысл в первую очередь, а в некоторых случаях - нет. Например, может быть, имеет смысл отдельно поддерживать коллекции для каждого основного типа учетной записи и иметь метод «getAllAccounts», который будет возвращать агрегат?

0
ответ дан 14 December 2019 в 01:16
поделиться

Зачем вам нужен «доступ к интерфейсу объектов производного класса»?

Для целей обсуждения может оказаться полезным, если вы предоставите пример подкласса BaseBankAccount с методом, который вы хочу вызвать.

Я предполагаю, что чистые методы в вашем классе BaseBankAccount также должны быть виртуальными?

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

Например,

class BaseBankAccount {
    public:
        BaseBankAccount() {}

        virtual void someNewMethod () = 0;

        // ...
};

class SavingsBankAccount : public BaseBankAccount {
    public:
        virtual void someNewMethod () {
            // ...
        }

        // ...
};
1
ответ дан 14 December 2019 в 01:16
поделиться
Другие вопросы по тегам:

Похожие вопросы: