2013-08-18 7 views
0

Я хочу создать библиотеку классов с использованием идиомы pimpl, чтобы я мог скрывать детали реализации для пользователя библиотеки.класс библиотека и доступность класса pimpl - разбиение класса

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

Прямо сейчас я вижу только решение с ключевым словом friend и объявлением внутренних методов private.

Например: MyPartiallyVisibleClass: класс, содержащий смесь доступных для пользователя методов и методы, доступные только для внутренних библиотек. Внутренний класс: класс внутри библиотеки. Пользователь никогда не узнает этого актера.

// MyPartiallyVisibleClass.h: Will be included by the user. 
class MyPartiallyVisibleClass 
{ 
private: 
    class Impl;   // Forward declare the implementation 
    Impl* pimpl; 

    InternalMethod(); // Can only be called from within the library-internals. 

public: 
    UserMethod();  // Will be visible and callable from users perspective. 
} 

// MyPartiallyVisibleClass.cpp 
class MyPartiallyVisibleClass::Impl 
{ 
private: 
    InternalMethod(); 

public: 
    UserMethod(); 

    friend class InternalClass; 
} 

// Internal class that will not be included into users application. 
class InternalClass 
{ 
public: 
    InternalMethod() 
    { 
     MyPartiallyVisibleClass pvc; 
     pvc.InternalMethod(); 
    } 
} 

Есть ли лучший способ сделать это?

+0

Зачем вам это нужно? Самый простой способ - поместить только общедоступные методы в пользовательский класс и оставить все детали gory для реализации (ов). – juanchopanza

+0

Повторяющийся кандидат: http://stackoverflow.com/questions/843389/the-pimpl-idiom-in-practice – lpapp

+0

НЕ ДУБЛИКАТ: этот вопрос более конкретный. если не рассматривать каждый вопрос, говорящий о pimpl дубликат ... –

ответ

0

Есть плюсы и минусы.

С точки зрения источника, если вы распространяете только заголовки и двоичные файлы, все, что находится в файлах cpp, не будет видно исходному пользователю.

Итак, также MyPartiallyVisibleClass::Impl::Usermethod не отображается, но является общедоступным, вызываемым везде в файле cpp, который объявляется.

Нулевой, односторонний или двухсторонний подход между внешним и внутренним классами может потребоваться, если вы не хотите повторять внешние методы внутренне. Это может показаться перерыв в инкапсуляции, но это не так, поскольку здесь «капсула» является внешним классом. Создание сложной иерархии внутренней конфиденциальности (публичная внешняя, частная внешняя, государственная внутренняя частная внутренняя общественность, еще более внутренняя ... и т. Д.) Может стать невежественной, если все будет под вашу ответственность. Если внутренняя часть не настолько велика, чтобы быть назначенной для разных разработчиков, так что требуется реализация другого уровня интерфейса &.

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

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

Существует также еще один недостаток: шаблоны не могут быть скрыты в источниках, поскольку они должны быть расширены в пространство исходного кода пользователя (а не двоичное пространство разработчика). И растущее общее программирование, функциональный статический полиморфизм и т. Д. Делает идиому pimpl менее привлекательной.

В настоящее время существует множество программ, созданных одним файлом cpp, который создает экземпляр одного «объекта-менеджера», вся функциональность которого хранится в виде только заголовков. Полагая или нет, этот способ программирования делает код еще более переносимым между компиляторами, поскольку он не должен существовать в другой двоичной форме для каждого возможного клиентского компилятора. И это не обязательно увеличивает время сборки: предварительно скомпилированный заголовок может быть сгенерирован один раз для кода, который не изменяется слишком часто. Кто заботится, пользователь видит код? Если он хочет использовать его и быть поддержанным, это не его интерес изменить его ненадлежащим образом. Если он хочет взломать или украсть, он все равно найдет другой способ сделать это.

+0

На самом деле, pimpl до сих пор довольно распространен, так что «все менее привлекательные» могут быть поняты другими. Это * все еще очень привлекательно. На самом деле, несмотря на этот пост, я лично предложил бы идиому pimpl для использования. Что, вероятно, хуже, это друзья с двумя друзьями. – lpapp

+0

@ LaszloPapp: тогда стандартная библиотека хуже, по крайней мере для вас. Но не волнуйтесь, это старые дебаты: см. Http://stackoverflow.com/questions/1093618/how-does-the-friend-keyword-class-function-break-encapsulation-in-c –

+0

Нет, у меня есть не сказал, что это в конечном счете плохо. Я сказал, что для этого сценария это неправильный вызов, ИМО. :-) – lpapp

 Смежные вопросы

  • Нет связанных вопросов^_^