Этот оператор определяет статический объект по имени interestRate, который является членом класса Account и имеет тип double. Подобно другим членам класса, определение статического находится в области видимости того класса, где определено его имя. В результате статическую функцию-член initRate() можно использовать для инициализации переменной rate непосредственно, без уточнения класса. Обратите внимание: несмотря на то, что функция-член initRate() является закрытой, ее можно использовать для инициализации объекта interestRate. Определение переменной-члена interestRate, подобно любому другому определению, находится в области видимости класса, а следовательно, имеет доступ к закрытым членам класса.

Наилучший способ гарантировать, что объект будет определен только один раз, — разместить определение статических переменных-членов в том же файле, который содержит определение не встраиваемых функций-членов класса.

Инициализация статических переменных-членов в классе

Обычно статические переменные-члены не могут быть инициализированы в теле класса. Но можно предоставить внутриклассовые инициализаторы для тех статических переменных-членов, которые имеют тип целочисленных констант, или статических членов constexpr литерального типа (см. раздел 7.5.6). Инициализаторы должны быть константными выражениями. Такие члены сами являются константными выражениями; они могут быть использованы там, где ожидается константное выражение. Например, инициализированную статическую переменную-член можно использовать для определения размерности члена типа массива:

class Account {

public:

 static double rate() { return interestRate; }

 static void rate(double);

private:

 static constexpr int period = 30; // period - константное выражение

 double daily_tbl[period];

};

Если член класса используется только в контекстах, где компилятор может подставить его значение, то инициализированная константа или статическое константное выражение не следует определять отдельно. Но если член класса используется в контексте, где значение не может быть подставлено, то определение для этого члена необходимо.

Например, если переменная period используется только для определения размерности массива daily_tbl, нет никакой необходимости определять ее за пределами класса Account. Но если пропустить определение, то даже, казалось бы, тривиальное изменение в программе может привести к отказу компиляции. Например, если передать переменную-член Account::period функции, получающей параметр типа const int&, то переменную period следует определить.

Если инициализатор предоставляется в классе, определение члена класса не должно задавать исходного значения:

// определение статического члена без инициализатора

constexpr int Account::period; // инициализатор предоставлен в

                               // определении класса

Даже если константная статическая переменная-член инициализируется в теле класса, она должна определяться вне определения класса.

Статические члены можно применять так, как нельзя применять обычные

Как уже упоминалось, статические члены существуют независимо от конкретного объекта. В результате они применимы такими способами, которые недопустимы для нестатических переменных-членов. Например, у статической переменной-члена может быть незавершенный тип (см. раздел 7.3.3). В частности, статическая переменная-член может иметь тип, совпадающий с типом класса, членом которого она является. Нестатическая переменная-член может быть только указателем или ссылкой на объект собственного класса:

class Bar {

public:

 // ...

private:

 static Bar mem1; // ok: тип статического члена может быть

                  // незавершенным

 Bar *mem2;       // ok: тип указателя-члена может быть незавершенным

 Bar mem3;        // ошибка: тип переменной-члена должен быть

                  // завершенным

};

Еще одно различие между статическими и обычными членами в том, что статический член можно использовать как аргумент по умолчанию (см. раздел 6.5.1):

class Screen {

public:

 // bkground ссылается на статический член класса

 // объявлено позже, в определении класса

 Screen& clear(char = bkground);

private:

 static const char bkground;

};

Перейти на страницу:

Похожие книги