Доступность пакета для функции и / или класса - PullRequest
6 голосов
/ 14 сентября 2010

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

Ответы [ 6 ]

2 голосов
/ 14 сентября 2010

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

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

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

1 голос
/ 14 сентября 2010

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

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

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

0 голосов
/ 16 февраля 2018

немного "поздно", но в случае, если другие люди высадятся здесь ...;)

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

Пример:

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

Вот полный пример (и его Постоянная ссылка ):

#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.
0 голосов
/ 14 сентября 2010

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

0 голосов
/ 14 сентября 2010

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

Заявленная видимость обычно понимается.

Видимость источника (если вы пришли с 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 голосов
/ 14 сентября 2010

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

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

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

...