Неопределенная ссылка на статического участника класса

191
задан codeling 18 December 2015 в 01:56
поделиться

4 ответа

Необходимо на самом деле определить статического участника где-нибудь (после определения класса). Попробуйте это:

class Foo { /* ... */ };

const int Foo::MEMBER;

int main() { /* ... */ }

, Который должен избавиться от неопределенной ссылки.

193
ответ дан Drew Hall 23 November 2019 в 05:34
поделиться

Проблема возникает из-за интересного столкновения новых функций C++ и что Вы пытаетесь сделать. Во-первых, давайте смотреть на push_back подпись:

void push_back(const T&)

Это ожидает ссылку на объект типа T. Под старой системой инициализации существует такой участник. Например, следующий код компилирует очень хорошо:

#include <vector>

class Foo {
public:
    static const int MEMBER;
};

const int Foo::MEMBER = 1; 

int main(){
    std::vector<int> v;
    v.push_back( Foo::MEMBER );       // undefined reference to `Foo::MEMBER'
    v.push_back( (int) Foo::MEMBER ); // OK  
    return 0;
}

Это вызвано тем, что существует фактический объект где-нибудь, которому сохранили то значение в нем. Если, однако, Вы переключаетесь на новый метод определения, что статические участники константы, как Вы имеют выше, Foo::MEMBER больше не объект. Это - константа, несколько сродни:

#define MEMBER 1

, Но без головных болей макроса препроцессора (и с безопасностью типов). Это означает, что вектор, который ожидает ссылку, не может получить тот.

73
ответ дан phoenix 23 November 2019 в 05:34
поделиться

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

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

при явном кастинге константы Вы создаете временный файл, и это - этот временный файл, который связывается со ссылкой (по специальным правилам в стандарте).

Это - действительно интересный случай, и я на самом деле думаю, что стоит поднять вопрос так, чтобы станд. быть измененным для имения того же поведения для постоянного участника!

, Хотя, в странном способе это могло рассматриваться как законное использование унарного '+' оператор. В основном результатом эти unary + является rvalue и таким образом, правила для привязки rvalues к ссылкам константы применяются, и мы не используем адрес нашего статического участника константы:

v.push_back( +Foo::MEMBER );
59
ответ дан Richard Corden 23 November 2019 в 05:34
поделиться

Никакая идея, почему бросок работает, но Foo:: УЧАСТНИК не выделяется до первого раза Foo загружается, и так как Вы никогда не загружаете его, он никогда не выделяется. Если бы у Вас была ссылка на Нечто где-нибудь, это, вероятно, работало бы.

1
ответ дан Paul Tomblin 23 November 2019 в 05:34
поделиться
Другие вопросы по тегам:

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