Что делать с закрытыми функциями-членами при превращении статического класса в пространство имен в C ++? - PullRequest
6 голосов
/ 17 января 2010

У меня есть класс, который имеет 5 статических общедоступных функций и 1 статическую частную функцию (вызывается из одной из общедоступных функций). В классе нет переменных-членов. Мне кажется, что это должно быть пространство имен, а не класс. Но что делать с частной функцией? Я предпочитаю, чтобы он не был доступен каждому пользователю пространства имен, но в пространствах имен нет контроля доступа.

Ответы [ 5 ]

13 голосов
/ 17 января 2010

Есть два способа, которыми я знаю

Не объявляйте их в шапке

Один из способов - не объявлять эти функции внутри заголовка. Они могут быть помещены в безымянные пространства имен только в файле реализации.

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

Поместите их в подробное пространство имен

Желательно, чтобы вы поместили их в другой заголовок и включили их. Поэтому их код не будет мешать заголовку вашего интерфейса. Вот как это делает boost:

#include "detail/destroy.hpp"

namespace orbit {
  void destroy() {
    detail::destroy_planets();
    detail::destroy_stars();
  }
}
8 голосов
/ 17 января 2010

Я не думаю, что есть решение этой проблемы:)

Одно решение -different- состояло бы в том, чтобы разделить эти функции на отдельный модуль компиляции, а затем объявить закрытые функции в анонимном пространстве имен.

4 голосов
/ 17 января 2010

Хранить публичную декларацию в заголовочном файле. Переместите реализации в файл cpp. Отметьте ранее private методы как static. Это сделает их недоступными для других объектов компоновщика (единиц компиляции) и эффективно их скрывает.

3 голосов
/ 17 января 2010

Мне кажется, это должен быть класс, а не пространство имен. Пространства имен в C ++ являются в первую очередь инструментами разрешения имен, и не предназначены в качестве основы для проектирования и не обеспечивают инкапсуляцию. Так что я бы оставил все как есть.

0 голосов
/ 17 января 2010

Другое решение, которое, однако, не позволяет полностью избавиться от классов, состоит в том, чтобы сохранить все частные функции в некотором классе в качестве статических методов и иметь открытые функции в пространстве имен. Затем разрешите открытым функциям использовать класс, используя friend:

#include <iostream>

// forward declaration of Module::PublicFn()
namespace Module {
    void PublicFn();
};

// static class for private functions (methods)
class ModulePrivates
{
private:
    // disallow instantiation by making constructor private
    ModulePrivates() { }
private:
    // example of a private function
    static void PrivateFn()
    {
        std::cout << "ModulePrivates::PrivateFn() called." << std::endl;
    }

    // allow public function to call PrivateFn()
    friend void Module::PublicFn();
};

// namespace for public functions
namespace Module
{
    void PublicFn()
    {
        std::cout << "Module::PublicFn() called." << std::endl;
        ModulePrivates::PrivateFn();
    }
};

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

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