#cpp #классы #static
Почему возникает ошибка? #includestruct A { void foo() { container.resize(2); container[0] = constant; // тут можно использовать //container.push_back(constant); // а тут ошибка линковки } std::vector container; static const int constant = 42; }; int main(){ A a; a.foo(); }
Ответы
Ответ 1
У вас все правильно написано за исключением того, что статическую переменную нужно определить вне класса, когда она, как написано в стандарте, ODR (One Definition Rule)-используется. #includestruct A { void foo() { container.resize(2); container[0] = constant; // тут можно использовать //container.push_back(constant); // а тут ошибка линковки } std::vector container; static const int constant = 42; }; const int A::constant; int main(){ A a; a.foo(); } Различие между предложениями container[0] = constant; // тут можно использовать container.push_back(constant); // а тут ошибка линковки состоит в том, что во втором случае (push_back) берется ссылка на объект, void push_back(const T& x); ^^ а потому объект должен быть определен. То есть, чтобы было более понятно, функция push_back внутри своего тела имеет дело с ссылкой на объект. Код этой функции уже был скомпилирован и помещен в библиотеку задолго до компиляции вашего кода. А потому компилятор в тело этой функции не может внести никакие изменения. Раз функция имеет дело с ссылкой на объект, то объект должен быть определен. Для первого случая это не требуется, так как компилятор просто может подставить значение константы в предложение container[0] = 42; //constant; на этапе компиляции определения вашего класса. Ответ 2
инициализируйте так #includestruct A { void foo() { container.resize(2); //container[0] = constant; // тут можно использовать container.push_back(constant); // а тут ошибка линковки } std::vector container; static const int constant; }; const int A::constant = 42; int main(){ A a; a.foo(); } Ответ 3
Значит, компилятор не в состоянии оптимизировать, и нужно определить constant отдельно (http://ideone.com/NTB4u8) static const int constant; }; const int constant = 42; Но, например, тот же VC++ 2015 совершенно спокойно скомпилировал и собрал исходный код.
Комментариев нет:
Отправить комментарий