бит 2mantissa + 1 + 1
+1 в экспоненте (бит мантиссы + 1) состоит в том, что если мантисса содержит abcdef...
, то число, которое оно представляет, фактически 1.abcdef... × 2^e
, обеспечивая дополнительный неявный бит точности.
Для float
это 16 777 217 (224 + 1). Для double
это 9 007 199 254 740 993 (253 + 1).
>>> 9007199254740993.0
9007199254740992
Вы должны использовать пространство имен, потому что пространство имен имеет много преимуществ перед классом:
using
члена класса; вы можете using
член пространства имен using class
, хотя using namespace
не так часто бывает хорошей идеей Статические члены, на мой взгляд, очень сильно злоупотребляют. В большинстве случаев они не являются реальной необходимостью. Функции статических членов, вероятно, лучше, чем функции области видимости, а статические члены данных - это просто глобальные объекты с лучшей, незаслуженной репутацией.
Есть много людей, которые не согласились бы со мной, но это то, как я это вижу:
Класс по существу является определением определенного типа объекта. Статические методы должны определять операции, которые тесно связаны с этим определением объекта.
Если вы просто собираетесь иметь группу связанных функций, не связанных с базовым объектом или определением типа объекта , то я бы сказал, что вы идете только с пространством имен. Для меня, концептуально, это гораздо более разумно.
Например, в вашем случае спросите себя: «Что такое MyMath?» Если MyMath
не определяет какой-либо объект, тогда I скажет: не делайте его классом.
Но, как я уже сказал, я знаю, что есть много люди, которые (даже яростно) не согласятся со мной на этом (в частности, разработчики Java и C #).
typedef
их использовать в качестве параметров шаблона и т. Д.
– Shog9♦
16 September 2009 в 20:27
Еще одна причина использования класса - вариант использования спецификаторов доступа. Затем вы можете разбить свой публичный статический метод на более мелкие частные методы. Открытый метод может вызывать несколько частных методов.
private
метод более доступен, чем метод, прототип которого вообще не публикуется в заголовке (и, таким образом, остается невидимым). Я даже не упоминаю о лучшей инкапсуляции, предлагаемой анонимными функциями с именами.
– paercebal
17 February 2012 в 20:00
.cpp
, который сделает его закрытым для этой единицы перевода, не передавая лишней информации никому, кто читает файл заголовка. Фактически, я пытаюсь отстаивать идиому PIMPL.
– nonsensickle
15 November 2015 в 05:09
.cpp
, если хотите использовать шаблоны.
– Yay295
16 July 2018 в 22:16
Я бы предпочел пространства имен, таким образом, вы можете иметь личные данные в анонимном пространстве имен в файле реализации (поэтому он не должен отображаться в заголовке вообще, а не private
). Другим преимуществом является то, что через using
ваше пространство имен клиенты методов могут отказаться от указания MyMath::
По умолчанию использовать функции с именами.
Классы должны создавать объекты, а не заменять пространства имен.
Скотт Мейерс написал целый предмет для своей эффективной книги на C ++ по этой теме: «Предпочитайте функции, не являющиеся членами-членами, для функций-членов». Я нашел онлайн-ссылку на этот принцип в статье из Herb Sutter: http://www.gotw.ca/gotw/084.htm
Важно знать, что: В C ++ функции в том же пространстве имен, что и класс, относятся к интерфейсу этого класса (поскольку ADL будет искать эти функции при разрешении вызовов функций ).
Функции имен, если только объявленный «друг» не имеет доступа к внутренним классам, тогда как статические методы имеют.
Это означает, например, что при сохранении вашего класса , если вам нужно изменить внутренние свойства вашего класса, вам нужно будет искать побочные эффекты во всех его методах, включая статические.
Добавление кода в класс '.
В C # вы можете добавлять методы в класс, даже если у вас нет доступа к нему. Но в C ++ это невозможно.
Но, все еще на C ++, вы все равно можете добавить функцию с именами, даже в класс, который кто-то написал для вас.
См. С другой стороны , это важно при разработке кода, потому что, помещая ваши функции в пространство имен, вы разрешаете вашим пользователям увеличивать / дополнять интерфейс класса.
Сторона -эффект предыдущей точки, невозможно объявить статические методы в нескольких заголовках. Каждый метод должен быть объявлен в одном классе.
Для пространств имен функции из одного и того же пространства имен могут быть объявлены в нескольких заголовках (наиболее подходящим примером является функция почти стандартной замены).
Основная прохлада пространства имен заключается в том, что в некотором коде вы можете не упоминать об этом, если используете ключевое слово «using»:
#include <string>
#include <vector>
// Etc.
{
using namespace std ;
// Now, everything from std is accessible without qualification
string s ; // Ok
vector v ; // Ok
}
string ss ; // COMPILATION ERROR
vector vv ; // COMPILATION ERROR
И вы можете даже ограничить «загрязнение» одним классом:
#include <string>
#include <vector>
{
using std::string ;
string s ; // Ok
vector v ; // COMPILATION ERROR
}
string ss ; // COMPILATION ERROR
vector vv ; // COMPILATION ERROR
Этот «шаблон» является обязательным для правильного использования почти стандартного икота свопа.
И это невозможно делать со статическими методами в классах.
Итак, пространства имен C ++ имеют свою собственную семантику.
Но она идет дальше, поскольку вы можете комбинировать пространства имен способом, подобным наследованию.
Например, если у вас есть пространство имен A с функцией AAA, пространство имен B с функцией BBB, вы можете объявить пространство имен C и привести AAA и BBB в это пространство имен с использованием ключевого слова.
Пространства имен для n amespaces. Классы предназначены для классов.
C ++ был разработан таким образом, что каждая концепция различна и используется по-разному в разных случаях как решение различных проблем.
Не используйте классы, когда вы нужны пространства имен.
И в вашем случае вам нужны пространства имен.
Оба метода пространства имен и класса имеют свои применения. Пространство имен имеет возможность распространяться по файлам, однако это слабость, если вам нужно обеспечить, чтобы весь связанный код включался в один файл. Как упоминалось выше, класс также позволяет создавать частные статические члены в классе. Вы можете использовать его в анонимном пространстве имен файла реализации, но он по-прежнему является большим объемом, чем наличие внутри класса.
private:
. и во многих случаях, когда требуется привилегированный доступ , i>, который может быть учтен. самая «частная» функция - та, которая не появляется в заголовке. private:
методы никогда не смогут пользоваться этим преимуществом.
– underscore_d
8 April 2016 в 13:45
В противном случае используйте функции с именами.
В ответ на комментарии: да, статические методы и статические данные имеют тенденцию быть чрезмерная эксплуатация. Вот почему я предложил только два сценария , связанные с , где я думаю, что они могут быть полезными. В конкретном примере OP (набор математических подпрограмм), если бы он хотел указать параметры, например, основной тип данных и точность вывода, которые будут применяться ко всем подпрограммам, он может сделать что-то вроде:
template<typename T, int decimalPlaces>
class MyMath
{
// routines operate on datatype T, preserving at least decimalPlaces precision
};
// math routines for manufacturing calculations
typedef MyMath<double, 4> CAMMath;
// math routines for on-screen displays
typedef MyMath<float, 2> PreviewMath;
Если вам это не нужно, тогда всеми средствами использует пространство имен.
template
!
– underscore_d
8 April 2016 в 13:40
inline
для удовлетворения ODR. – Thomas Eding 6 December 2012 в 01:24inline
, и это НЕ "встраивание" тело функции. реальная i> (и гарантированная стандартной) цельюinline
заключается в предотвращении множества определений. Читайте о «Правиле с одним определением». для C ++. Кроме того, связанный вопрос SO не собирался из-за предварительно скомпилированных проблем заголовков, а не проблем с ODR. – Thomas Eding 6 December 2012 в 20:33