Как вы создаете статический класс в C ++? Я должен быть в состоянии сделать что-то вроде:
cout << "bit 5 is " << BitParser::getBitAt(buffer, 5) << endl;
Предполагая, что я создал BitParser
класс. Как будет BitParser
выглядеть определение класса?
Ответы:
Если вы ищете способ применения «статического» ключевого слова к классу, как, например, в C #, вы не сможете без использования Managed C ++.
Но, судя по вашему образцу, вам просто нужно создать публичный статический метод для вашего объекта BitParser. Вот так:
BitParser.h
BitParser.cpp
Вы можете использовать этот код для вызова метода так же, как ваш пример кода.
Надеюсь, это поможет! Приветствия.
источник
private: BitParser() {}
Это не позволит никому создавать экземпляры.BitParser() = delete;
правильно передать намерение удалить конструктор (а не просто скрыть его какprivate
).Рассмотрим решение Мэтта Прайса .
В семантике C ++ вы хотите поместить свою функцию (поскольку она является функцией) в пространство имен.
Редактировать 2011-11-11
В C ++ нет «статического класса». Ближайшим понятием будет класс с только статическими методами. Например:
Но вы должны помнить, что «статические классы» - это хаки в Java-подобных языках (например, C #), которые не могут иметь функции, не являющиеся членами, поэтому вместо этого им нужно перемещать их внутри классов как статические методы.
В C ++ вам действительно нужна функция, не являющаяся членом, которую вы объявляете в пространстве имен:
Это почему?
В C ++ пространство имен более мощное, чем классы для шаблона «статический метод Java», потому что:
Вывод: не копируйте / вставляйте этот шаблон Java / C # в C ++. В Java / C # шаблон является обязательным. Но в C ++ это плохой стиль.
Редактировать 2010-06-10
Был аргумент в пользу статического метода, потому что иногда нужно использовать статическую закрытую переменную-член.
Я не согласен, как показано ниже:
Решение "Static private member"
Во-первых, myGlobal называется myGlobal, потому что это все еще глобальная частная переменная. Взгляд на источник CPP прояснит, что:
На первый взгляд, тот факт, что свободная функция barC не может получить доступ к Foo :: myGlobal, кажется хорошей вещью с точки зрения инкапсуляции ... Это круто, потому что кто-то, глядя на ГЭС, не сможет (если не прибегнет к саботажу) получить доступ Foo :: myGlobal.
Но если вы внимательно посмотрите на это, то обнаружите, что это колоссальная ошибка: не только ваша частная переменная все равно должна быть объявлена в ГЭС (и, таким образом, видимой для всего мира, несмотря на то, что является частной), но вы должны объявить в той же ГЭС все (как во ВСЕХ) функции, которым будет разрешен доступ к ней !!!
Таким образом, использование закрытого статического члена - это все равно, что выходить на улицу в обнаженном виде со списком своих любовников, нанесенных татуировкой на вашей коже: никто не имеет права прикасаться, но каждый может посмотреть. И бонус: у каждого могут быть имена тех, кому разрешено играть с вашими друзьями.
private
действительно ... :-DРешение "Анонимные пространства имен"
Преимущество анонимных пространств имен в том, что они становятся частными.
Во-первых, заголовок ГЭС
Просто чтобы убедиться, что вы заметили: нет ни бесполезного объявления ни barB, ни myGlobal. Это означает, что никто, читающий заголовок, не знает, что скрыто за barA.
Затем CPP:
Как вы можете видеть, как и так называемое объявление «статического класса», fooA и fooB по-прежнему могут обращаться к myGlobal. Но никто не может. И никто за пределами этого CPP не знает fooB и myGlobal, даже существуют!
В отличие от «статического класса», ходящего по обнаженной фигуре с ее адресной книгой, вытатуированной на ее коже, «анонимное» пространство имен полностью одето , что, как представляется, лучше инкапсулировано в AFAIK.
Это действительно имеет значение?
Если только пользователи вашего кода не являются диверсантами (в качестве упражнения я позволю вам выяснить, как можно получить доступ к закрытой части открытого класса с помощью хакерского поведения с неопределенным поведением ...), что
private
этоprivate
, даже если оно виден вprivate
разделе класса, объявленном в заголовке.Тем не менее, если вам нужно добавить еще одну «приватную функцию» с доступом к приватному члену, вы все равно должны объявить ее всему миру, изменив заголовок, что для меня является парадоксом: если я изменю реализацию мой код (часть CPP), тогда интерфейс (часть HPP) НЕ должен изменяться. Цитируя Леонидаса: « Это ЗАДЕРЖКА! »
Изменить 2014-09-20
Когда классы статические методы на самом деле лучше, чем пространства имен с функциями, не являющимися членами?
Когда вам нужно сгруппировать функции и передать эту группу в шаблон:
Потому что, если класс может быть параметром шаблона, пространства имен не могут.
источник
#define private public
в заголовки ... ^ _ ^ ...utilities
пространстве имен. Таким образом, эта функция может быть проверена модулем и все еще не имеет специального доступа к закрытым членам (так как они задаются в качестве параметров при вызове функции) ...namespace
волю, он не получит доступ к вашимglobal
, хотя и скрытым, участникам? Очевидно, им придется угадывать, но если вы не намеренно запутываете свой код, имена переменных довольно легко угадать.Вы также можете создать бесплатную функцию в пространстве имен:
В BitParser.h
В BitParser.cpp
В общем, это был бы предпочтительный способ написания кода. Когда нет необходимости в объекте, не используйте класс.
источник
статические классы - это просто компилятор, который держит вас за руку и мешает писать любые методы / переменные экземпляра.
Если вы просто пишете обычный класс без каких-либо методов / переменных экземпляра, это то же самое, и это то, что вы делаете в C ++.
источник
static
было бы хорошо, если бы кто-то держал меня за компилятор, чтобы я не писал и не вырезал / вставил слово 200 раз.В C ++ вы хотите создать статическую функцию класса (не статический класс).
После этого вы сможете вызывать функцию, используя BitParser :: getBitAt (), не создавая объект, который, как я предполагаю, является желаемым результатом.
источник
Могу ли я написать что-то вроде
static class
?Нет , согласно проекту стандарта C ++ 11 N3337, Приложение C 7.1.1:
И, как
struct
,class
также объявление типа.То же самое можно сделать, пройдя по синтаксическому дереву в Приложении А.
Интересно отметить, что это
static struct
было допустимо в C, но не имело никакого эффекта: зачем и когда использовать статические структуры в C-программировании?источник
Как уже отмечалось, лучшим способом достижения этого в C ++ может быть использование пространств имен. Но поскольку здесь никто не упомянул
final
ключевое слово, я публикую пост ,static class
как будет выглядеть прямой эквивалент C # в C ++ 11 или более поздней версии :источник
Вы можете «иметь» статический класс в C ++, как упоминалось ранее, статический класс - это класс, в котором нет объектов, для которых он создан. В C ++ это можно получить, объявив конструктор / деструктор как закрытый. Конечный результат такой же.
источник
В Managed C ++ синтаксис статического класса:
... лучше поздно, чем никогда...
источник
Это похоже на способ C # сделать это в C ++
В C # file.cs вы можете иметь приватную переменную внутри публичной функции. Когда в другом файле вы можете использовать его, вызывая пространство имен с помощью функции, как в:
Вот как сделать то же самое в C ++:
SharedModule.h
SharedModule.cpp
OtherFile.h
OtherFile.cpp
источник
В отличие от других управляемых языков программирования, «статический класс» не имеет значения в C ++. Вы можете использовать статическую функцию-член.
источник
Один случай, когда пространства имен могут быть не очень полезны для достижения «статических классов», - это использование этих классов для достижения композиции по наследованию. Пространства имен не могут быть друзьями классов и поэтому не могут получить доступ к закрытым членам класса.
источник
Один (из многих) альтернативный, но наиболее (на мой взгляд) элегантный (по сравнению с использованием пространств имен и частных конструкторов для эмуляции статического поведения) способ достижения поведения «класс, который не может быть создан» в C ++ состоит в объявить фиктивную чисто виртуальную функцию с
private
модификатором доступа.Если вы используете C ++ 11, вы можете пройти лишнюю милю, чтобы гарантировать, что класс не наследуется (просто эмулировать поведение статического класса), используя
final
спецификатор в объявлении класса, чтобы ограничить другие классы от его наследования. ,Как бы глупо и нелогично это ни звучало, C ++ 11 позволяет объявлять «чисто виртуальную функцию, которая не может быть переопределена», которую вы можете использовать вместе с объявлением класса
final
для полной и полной реализации статического поведения, так как это приводит к результирующему результату. класс не должен быть наследуемым, а фиктивная функция никоим образом не должна быть переопределена.источник