Шаблон проектирования C ++: возможно ли унаследовать метод, частный для производного класса? - PullRequest
1 голос
/ 16 мая 2011

Возможен ли следующий шаблон настройки / проектирования в C ++?

  • a класс Leader
  • a класс Worker
    • имеет метод M ()
  • a Класс MyWorker (наследует Worker)

Класс Leader имеет много рабочих и должен вызывать метод M () из класса Worker.Однако я не хочу, чтобы какая-либо реализация Worker (например, MyWorker) имела доступ к методу M ().Похоже, что ни общедоступные, ни частные, ни защищенные в этом случае не работают.

Возможна ли эта настройка?Или как мне конструировать вещи иначе?

Спасибо

Редактировать: (добавление примера)

Предположим, M () - это GiveMoney (), Leader = Parent и Worker =Ребенок.Я только хочу, чтобы Родитель мог дать Ребенку деньги (а Дети не могут сами дать деньги).

Ответы [ 5 ]

1 голос
/ 16 мая 2011

Вы можете либо:

  1. Сделать M() закрытой функцией в Worker и объявить Leader другом Worker.
  2. Переместите логику для M() из Worker в Leader. Лично я бы выбрал такой подход, учитывая, что независимо от того, что делает M(), вы не хотите, чтобы другие Worker делали.
0 голосов
/ 16 мая 2011

Имейте M личное и объявите Leader как друга Worker. Вы все еще можете реализовать M в производных классах Worker:

class Leader;

class Worker
{
    virtual void M() = 0;
    friend class Leader;
};

class Leader
{
    Worker* w;

public:
    void doSomething() { w->M(); }
};

class MyWorker : public Worker
{
    void M() { ... } // No problem. Even if `M` is private in the base class, it
                     // can still be overridden, but not accessed.
};
0 голосов
/ 16 мая 2011

Звучит так, как будто вы должны взглянуть на шаблон проектирования Visitor: http://en.wikipedia.org/wiki/Visitor_pattern

Это не совсем тот же подход, но я верю, если вы определите метод Visit(Worker) для класса Leader и *Метод 1006 * в классе Worker, который затем вызывает private M(), позволяет получить требуемую функциональность.

Учитывая, что мое сообщение было отклонено, я решил, что это может помочь, если я дам немного большеинформация:

class Leader;

class Worker
{
virtual void M() = 0;
public:
    void Accept( const Leader & w)
        {
            M();
        }
};

class Leader
{
public:
void Visit ( Worker & w) const
    {
    w.Accept(*this);
    }
};

class MyWorker : public Worker
{
virtual void M()
    {
    std::cout << "M()" << std::endl;
    }
};


int main(int argc, char **argv)
{
Leader l;
MyWorker myW;
myW.Accept(l)
return 0;
}

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

0 голосов
/ 16 мая 2011

Почему вы хотите это сделать? Чего вы на самом деле пытаетесь достичь? Знание вашей конечной цели поможет нам найти ответ, который вы ищете.

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

Редактировать Звучит так, будто вы делаете жизнь излишне сложной для себя. Если кто-то еще не контролирует реализацию детского работника, почему бы просто не попросить дать денег от детского работника?

Нечто подобное может подойти для вашего примера:

class Parent // Leader
{
private:
    Child* m_pChildren;
};

class Child : public ChildSelf
{
public:
    char GiveMoney() { return 'm'; }
};

class ChildSelf
{
    Run();
    Jump();
    ClimbTrees();
};

class MyChild : public ChildSelf
{
    void RunFaster() { Run(); Run(); }
};

Ваши детские рабочие реализации имеют доступ только к ChildSelf, который обеспечивает уровень безопасности, который вы ищете ..?

0 голосов
/ 16 мая 2011

Примерно так:

#include <iostream>

class Leader
{
  private:
    virtual char M() = 0;
  public:
    void foo() { std::cout << M(); }
};

class Worker : public Leader
{
  private:
    virtual char M() { return 'm'; }
};

Затем

int main()
{
  Worker w;
  w.foo();
}

выводит m и

class MyWorker : public Worker
{
  void foo2() { std::cout << M(); }
};

, что приводит к ошибке компиляции, сообщая, что

'virtual char Worker :: M ()' является приватным.

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