2010-09-14 3 views
4

В Java у них есть спецификатор доступа к пакету, который позволяет использовать эту функцию только классами из этого же «пакета» (пространство имен), и я вижу хорошие вещи об этом. Особенно, когда дизайн моделей находится в игре. Считаете ли вы, что что-то подобное может быть полезно в C++?
Спасибо.Доступность пакета для функции и/или класса

ответ

0

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

Декларируемая видимость обычно понимается.

Исходная видимость (если вы исходите из Java) немного отличается.

Java: у вас есть один файл для интерфейса объекта/реализации. Cpp: у вас есть один файл для интерфейса. реализация может заключаться в интерфейсе или одном или нескольких файлах реализации (cpp, cxx).

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

Было бы полезно в C++ ... это неплохо, хотя я лично считаю, что для языка существуют более высокие приоритеты.

пример видимости источника:

/* publicly visible header file */ 

namespace MON { 
class t_button { 
protected: 
    t_button(); 
    virtual ~t_button(); 
public: 
    typedef enum { Default = 0, Glowing = 1 } ButtonType; 
    /* ... all public virtual methods for this family of buttons - aka the public interface ... */ 
public: 
    t_button* CreateButtonOfType(const ButtonType& type); 
}; 
} 

/* implementation file -- not visible to clients */ 

namespace MON { 
namespace Private { 
class t_glowing_button : public t_button { 
public: 
    t_glowing_button(); 
    virtual ~t_glowing_button(); 
public: 
    /* ... impl ... */ 
}; 
} 
} 

MON::t_button* MON::t_button::CreateButtonOfType(const ButtonType& type) { 
    switch (type) { 
     case Glowing : 
      return new Private::t_glowing_button(); 

     case Default : 
      return new Private::t_glowing_button(); 

      /* .... */ 
     default : 
      break; 
    } 

    /* ... */ 
    return 0; 
} 
+0

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

+0

, если светящаяся кнопка (в только что добавленном примере) видна другим классам/интерфейсам, тогда она может использоваться. как вы организуете библиотеку, может быть очень важно (или вообще нет), в зависимости от того, насколько вы хотели бы абстрагироваться. fwiw, C++ также предоставляет 'friend's. поэтому ... cpp имеет * самую * функциональность Java в этом отношении (видимость). Вероятно, поэтому функция видимости пакета не является для меня первоочередной задачей. – justin

0

В C++, если вам это нужно, используйте классы.

IMO, правила доступа достаточно сложны, как есть.

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

+0

Я не думаю, что со статическим FNC вы могли бы добиться этого. Скажем, у вас есть класс A с только статическими членами. Вы все равно можете получить доступ к этим членам за пределами пространства имен, в котором объявлен этот класс. И я не понимаю, как вы можете добиться этого, используя классы? Вы можете остановиться на этом? –

+0

@ A-ha просто меняет видимость статической функции на личную, а затем пытается использовать ее за пределами класса - вы увидите, как это эффективное средство, позволяющее клиентам использовать частные реализации. компилятор отклонит программу. – justin

+0

@ Justin да, но это также ограничит использование других функций другими классами, и все дело в том, чтобы сделать их доступными только для классов в этом же пространстве имен. Таким образом, они могут взаимодействовать с этим классом, но только если они находятся в том же пространстве имен, в котором этот класс. –

1

Java, пакет примерно:

  • Способ группировки исходных файлов
  • Создание сжатых двоичных файлов

В C++ первое может быть достигнуто путем разумного использования namespace. Однако нет возможности эмулировать последнее, используя языковую конструкцию.

0

вы можете предоставить файл заголовка, который должен быть «общественность» для пользователей «пакета». Материалы, которые должны использоваться только внутри, могут иметь заголовочные файлы в папке с именем «internal» или (имя пакета). Это не мешает кому-то фактически включать эти файлы, но вы общаетесь с тем, что он не должен!

2

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

В основном друзья избегали в C++, поскольку они имеют тенденцию к увеличению сцепления

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

0

«немного» поздно, но в случае, когда другие люди земли здесь ...;)

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

Пример:

class Package 
{ 
public: 
    class Public; 
private: 
    class Private; 
}; 
  • Любой человек может использовать общественные классы.
  • Только классы из Пакета могут использовать частные классы.

Вот полный пример (и его permalink):

#include <iostream> 

// Package.hpp 

class Package 
{ 
public: 
    Package() = delete; 

    class PublicClass; 

private: 
    class PrivateClass; 
}; 

// PrivateClass.hpp/cpp 

class Package::PrivateClass 
{ 
public: 
    PrivateClass() 
    { 
     std::cout << "PrivateClass only usable by Package classes.\n"; 
    } 

private: 
    void Forbidden() {} 
}; 

// PrivateClass.hpp/cpp 

class Package::PublicClass 
{ 
public: 
    PublicClass() 
    { 
     std::cout << "PublicClass usable from outside/inside Package.\n"; 
     Package::PrivateClass privateClass; 
     // privateClass.Forbidden(); // error: 'Forbidden' is a private member of 'Package::PrivateClass' 
    } 
}; 

// main.cpp 

int main() 
{ 
    // Package package; // error: call to deleted constructor of 'Package'. 

    Package::PublicClass publicClass; 
    //Package::PrivateClass privateClass; // error: 'PrivateClass' is a private member of 'Package' 

    return EXIT_SUCCESS; 
} 

// Output: 
// ------- 
// PublicClass usable from outside/inside Package. 
// PrivateClass only usable by Package classes. 
Смежные вопросы