Действительно ли это - надлежащий способ использовать статическую переменную константы? В моем высокоуровневом классе (Форма)
#ifndef SHAPE_H
#define SHAPE_H
class Shape
{
public:
static const double pi;
private:
double originX;
double originY;
};
const double Shape::pi = 3.14159265;
#endif
И затем позже в классе, который расширяет Форму, я использую Форму:: пи. Я получаю ошибку компоновщика. Я переместил константу двойная Форма:: пи = 3.14... в файл Shape.cpp и мою программу затем компилирует. Почему это происходит?спасибо.
Поскольку const double Shape :: pi = 3.14159265;
- это определение Shape :: pi
, а C ++ допускает только одно определение символа (называется правилом одного определения , которое вы можете увидеть в его сокращенной форме ODR). Когда определение находится в файле заголовка, каждая единица перевода получает собственное определение, которое нарушает это правило.
Переместив его в исходный файл, вы получите только одно определение.
Статические элементы данных с плавающей запятой должны быть определены и инициализированы в исходном файле. Правило одного определения запрещает определение вне блока class {}
в заголовке, и только целые элементы данных могут быть инициализированы внутри блока class {}
.
Это также прискорбно, потому что, будучи алгебраическим значением, наличие немедленного значения под рукой может быть полезно для оптимизации, а не для загрузки из глобальной переменной. (Хотя разница, скорее всего, будет несущественной.)
Но решение есть!
class Shape
{
public:
static double pi()
{ return 3.14159265; }
private:
double originX;
double originY;
};
Встроенные определения функций, в том числе статические, разрешены внутри блока class {}
.
Также я рекомендую использовать M_PI
из
, который вы также должны получить из
.
Это происходит из-за того, что вы не можете определить Shape :: pi более одного раза. Он определяется один раз, когда вы включаете Shape.h в Shape.cpp, а затем снова каждый раз, когда вы используете Shape.h в другом файле cpp. Когда вы идете связать вашу программу вместе, компоновщик заблокируется из-за нескольких определений.
Строка const double Shape::pi = 3.14159265;
должна быть в вашем файле Shape.cpp. Заголовочный файл предназначен для объявления переменных. Вы можете определить переменную только один раз, поэтому это должно быть сделано в .cpp
. В заголовочном файле говорится, как использовать эти переменные и функции, а в файле cpp - что делать.
Для примитивных типов данных (таких как int, double, но не char []) вы также можете определить константу в определении класса в файле заголовка, например:
class Shape
{
public:
static const double pi = 3.14159265;
private:
double originX;
double originY;
};
Это позволит лучше оптимизировать компилятор.
Изменить: Как указал Деннис ниже, это разрешено только для целочисленных типов, но не для типов данных double или float (однако некоторые компиляторы это допускают).