Статический константный доступ в C ++ через нулевой указатель [duplicate]

12
задан sirg3 17 August 2010 в 00:24
поделиться

5 ответов

Вы можете использовать указатель (или другое выражение) для доступа к статическому члену; однако, к сожалению, выполнение этого с помощью указателя NULL официально является неопределенным поведением. Из 9.4 / 2 «Статические члены»:

Статические члены класса X могут быть упоминается с использованием квалифицированного идентификатора выражение X :: s; это не обязательно использовать синтаксис доступа к членам класса (5.2.5) для ссылки на статический член. А статический член может упоминаться с использованием синтаксис доступа к членам класса, в в этом случае объект-выражение оценен.

На основе следующего примера:

class process {
public:
    static void reschedule();
};

process& g();

void f()
{
    process::reschedule();   // OK: no object necessary
    g().reschedule();        // g() is called
}

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

10
ответ дан 2 December 2019 в 21:01
поделиться

Я считаю, что фактическое значение типа вообще не используется при вызове

bar->kType

поскольку kType статичен, а bar имеет тип Foo, это то же самое, что и вызов

Foo::kType

который вы должны делать в любом случае для ясности.

Вызов bar->kType выдает предупреждение компилятора на большинстве платформ по этой причине.

3
ответ дан 2 December 2019 в 21:01
поделиться

Даже если это сработало, это ужасный код.

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

Одно из следствий этого кода: является ли указатель NULL или нет, это даже не вопрос, но это означает, что этот член kType не может быть простым нестатическим членом класса. Иногда классы большие (это тоже зло), и не всегда можно перепроверить определение каждой переменной.

Будьте строги. И вызывайте все свои статические члены только таким образом:

Foo::kType

Другая возможность - следовать соглашению о кодировании, которое сообщает, что член является статическим, например, префикс s_ для всех статических членов класса:

Foo::s_kType
1
ответ дан 2 December 2019 в 21:01
поделиться

Помимо проблемы доступа через указатель NULL, есть еще одна тонкая проблема в коде

$ 9.4.2 / 2 - «Объявление статического элемента данных в определении его класса. не является определением и может иметь неполный тип, отличный от void с квалификацией cv. Определение статического члена данных должно появиться в области пространства имен, включающей определение класса члена. "

$ 9.4.2 / 4-" Если a Статический элемент данных имеет тип константного интегрального или константного перечисления, его объявление в определении класса может указывать инициализатор константы, который должен быть интегральным константным выражением (5.19). В этом случае член может появляться в интегральных константных выражениях. должен по-прежнему быть определен в области пространства имен, если она используется в программе, а определение области пространства имен не должно содержать инициализатор »

class Foo { 
public: 
 static const int kType = 42; 
}; 

int const Foo::kType;

void Func() { 
 Foo *bar = NULL; 
 int x = bar->kType; 
 putc(x, stderr); 
}

. Итак, еще одна причина для UB в коде OP.

1
ответ дан 2 December 2019 в 21:01
поделиться

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

Вы можете попробовать несколько вариантов, если хотите — например, сделать указатель параметром функции, результатом функции, оставить указатель неинициализированным (наилучший шанс вызвать жалобу компилятора), выполнить прямое приведение 0 (наилучший шанс остаться без жалоб).

-1
ответ дан 2 December 2019 в 21:01
поделиться
Другие вопросы по тегам:

Похожие вопросы: