Запретить создание класса, все функции которого являются статическими - PullRequest
9 голосов
/ 09 декабря 2008

Все переменные-члены и функции-члены в моем классе ClassA являются статическими.

Если пользователь пытается (по ошибке) создать объект этого класса, он получает предупреждение: «ClassA, локальная переменная никогда не ссылается», потому что все функции статические, поэтому на этот объект никогда не ссылаются. Итак, я хочу запретить пользователю пытаться создать объект этого класса.

Будет ли достаточно создать частный конструктор по умолчанию (без переменных)? Или я должен также создать частный конструктор копирования и частный оператор присваивания (чтобы не использовать конструкторы по умолчанию)? И если мне придется создавать их тоже, может быть, было бы лучше просто создать вместо них какую-нибудь фиктивную чистую виртуальную функцию, и это помешает пользователю создать объект?

Спасибо

Ответы [ 5 ]

20 голосов
/ 09 декабря 2008

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

namespace::function() вместо classname::function()

и вам не нужно иметь дело с кем-то, пытающимся создать экземпляр вашего класса.

11 голосов
/ 09 декабря 2008

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

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

10 голосов
/ 09 декабря 2008

Как говорили другие, вам следует использовать пространство имен. Если вы хотите остаться с вашим классом, создайте класс, который имеет приватный конструктор, и наследуйте его, чтобы сделать ваше намерение очевидным:

class NonConstructible { 
    NonConstructible();
};

class SuperUtils: NonConstructible {
    static void foo();
    // ...
    static std::vector<int> globalIDs;
    // ...
};

Хорошо, теперь давайте посмотрим на пространство имен, которое является единственным и единственным способом сделать это:

namespace SuperUtils {
    void foo() {
        // ....
    }

    std::vector<int> globalIDs;
};

Вы можете вызвать это, используя SuperUtils::foo(); в обоих случаях, но пространство имен имеет то преимущество, что в области вы можете использовать декларацию и директиву пространства имен, чтобы привести определенных или всех членов в текущую область, чтобы вы могли ссылаться на них без использования SuperUtils:::

void superFunction() {
    using namespace SuperUtils;
    foo();
}

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

3 голосов
/ 09 декабря 2008

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

0 голосов
/ 10 декабря 2008

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

...