Закрытый метод в интерфейсе C++?

Почему я хотел бы определить интерфейс C++, который содержит закрытые методы?

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

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

Вы могли также определить друга класс, который использует некоторые закрытые методы от нашего класса, и так реализация силы через интерфейс. Это могло быть аргументом.

Что другими аргументами являются для определения закрытые методы в интерфейсе в C++?

6
задан gavri 22 July 2010 в 08:47
поделиться

4 ответа

Обычное объектно-ориентированное представление состоит в том, что интерфейс устанавливает единый контракт, который определяет, как используются объекты, соответствующие этому интерфейсу, и как они себя ведут. Идиома или паттерн NVI, я никогда не знаю, когда одно становится другим, предлагает изменить этот образ мышления путем разделения интерфейса на два отдельных контракта:

  • как интерфейс должен использоваться
  • что должны предлагать производные классы

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

Это может быть полезно в разных случаях, во-первых, когда поведение является обычным, но его можно параметризовать только определенными способами с помощью общего скелета алгоритма. Затем алгоритм может быть реализован в базовом классе, а точки расширения - в производных элементах. В языках без множественного наследования это должно быть реализовано путем разделения на класс, реализующий алгоритм, основанный на некоторых параметрах, которые соответствуют другому «частному» интерфейсу. Я использую здесь «частный» в том смысле, что только ваш класс будет использовать этот интерфейс.

Второе распространенное использование состоит в том, что с помощью идиомы NVI можно просто инструментировать код, изменяя только на базовом уровне:

class Base {
public:
   void foo() { 
      foo_impl();
   }
private:
   virtual void foo_impl() = 0;
};

Дополнительные затраты на написание диспетчера foo () {foo_impl (); } довольно мал, и он позволяет вам позже добавить механизм блокировки, если вы конвертируете код в многопоточное приложение, добавляете ведение журнала к каждому вызову или таймер, чтобы проверить, сколько различных реализаций занимает каждая функция ... Поскольку фактический метод, который реализован в производных классах, является частным на этом уровне, вам гарантируется, что все полиморфные вызовы могут быть инструментированы в одной точке: в основе (это не блокирует расширяющиеся классы от создания foo_impl общественного мнения )

void Base::foo() {
   scoped_log log( "calling foo" ); // we can add traces
   lock l(mutex);                   // thread safety
   foo_impl();
}

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

6
ответ дан 8 December 2019 в 18:30
поделиться

Вы можете объявить частный виртуальный метод, цель которого должна быть производной. Пример:

class CharacterDrawer {
public:
   virtual ~CharacterDrawer() = 0;

   // draws the character after calling getPosition(), getAnimation(), etc.
   void  draw(GraphicsContext&);

   // other methods
   void  setLightPosition(const Vector&);

   enum Animation {
      ...
   };

private:
   virtual Vector getPosition() = 0;
   virtual Quaternion getRotation() = 0;
   virtual Animation getAnimation() = 0;
   virtual float getAnimationPercent() = 0;
};

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

Преимущество такого подхода, вместо того, чтобы использовать "setPosition", "setAnimation" и т.д., в том, что вам не нужно "толкать" значение в каждом кадре, вместо этого вы "тянете" его.

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

3
ответ дан 8 December 2019 в 18:30
поделиться

Зачем мне определять C ++ интерфейс, содержащий частный методы?

Вопрос несколько двусмысленный / противоречивый: если вы определяете (чисто) интерфейс, это означает, что вы определяете публичный доступ ко всему, что к нему подключается. В этом смысле вы не определяете интерфейс, содержащий частные методы.

Думаю, ваш вопрос связан с путаницей абстрактного базового класса с интерфейсом (поправьте меня, если я ошибаюсь).

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

На практике редко требуется иметь чистые виртуальные базовые классы без какой-либо реализации (т.е. базовые классы, которые определяют только список чистых виртуальных функций и ничего больше). Один случай, когда это требуется, - это программирование COM / DCOM / XPCOM (и есть другие). Хотя в большинстве случаев имеет смысл добавить некоторую частную реализацию к вашему абстрактному базовому классу.

3
ответ дан 8 December 2019 в 18:30
поделиться

В реализации шаблонного метода можно использовать для добавления ограничения специализации: вы не можете вызвать виртуальный метод базового класса из производного класса (иначе метод будет объявлен как protected в базовом классе):

class Base
{
private:
   virtual void V() { /*some logic here, not accessible directly from Derived*/}
};

class Derived: public Base
{
private:
   virtual void V() 
   { 
      Base::V(); // Not allowed: Base::V is not visible from Derived
   }
};
1
ответ дан 8 December 2019 в 18:30
поделиться
Другие вопросы по тегам:

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