LINUX.ORG.RU

Почему ругается линкер


0

0

Почему на следующий код ругается линкер:

class Q {
public:
static const int C = 0;
Q();
};

#include "inc.h"
#include <QtCore>

Q::Q() {
QVector<int> tt;
tt.append(C);
}

debug/inc.o(.text+0x14b): In function `ZN1QC2Ev':
D:/Workspaces/CppGeneWorkspace/ZTest2/src/inc.cpp:8: undefined reference to `Q::C'
debug/inc.o(.text+0x20d): In function `ZN1QC1Ev':
D:/Workspaces/CppGeneWorkspace/ZTest2/src/inc.cpp:8: undefined reference to `Q::C'

Собираю так:

g++ -c -g -frtti -fexceptions -mthreads -Wall -DUNICODE -DQT_LARGEFILE_SUPPORT -DQT_DLL -DQT_GUI_LIB -DQT_CORE_LIB -DQT_THREAD_SUPPORT -DQT_NEEDS_QMAIN -I"c:\qt4.3.3\include\QtCore" -I"c:\qt4.3.3\include\QtCore" -I"c:\qt4.3.3\include\QtGui" -I"c:\qt4.3.3\include\QtGui" -I"c:\qt4.3.3\include" -I"c:\qt4.3.3\include\ActiveQt" -I"debug" -I"." -I"c:\qt4.3.3\mkspecs\win32-g++" -o debug\inc.o src\inc.cpp
src\inc.cpp:9:2: warning: no newline at end of file

g++ -enable-stdcall-fixup -Wl,-enable-auto-import -Wl,-enable-runtime-pseudo-reloc -mthreads -Wl -Wl,-subsystem,windows -o debug\ZTest2.exe debug/inc.o debug/main.o -L"c:\qt4.3.3\lib" -lmingw32 -lqtmaind -lQtGuid4 -lQtCored4

mingw 4.3.2

anonymous

>undefined reference to `Q::C'

попробуй вынести инициализацию атрибута C за пределы определения класса:

const int Q::C = 0;

ale ★★
()

static инициируются вне класса

anonymous
()
Ответ на: комментарий от ale

Спасибо, помогло.

Такой вопрос. При использовании этой константы в программе, значение непосредственно будет подставлять сразу по месту использования, или там будет выполняться какой то код для доступа к значению?

anonymous
()
Ответ на: комментарий от anonymous

>Такой вопрос. При использовании этой константы в программе, значение непосредственно будет подставлять сразу по месту использования, или там будет выполняться какой то код для доступа к значению?

это зависит от того, где инициализировано Q::C. Если впределах компилируемого файла инициализированно Q::C, то вместо обращения к Q::C будет подставляться непосредственно его значение, иначе - будет обращение к статическому атрибуту класса. Т.е. если поместить инициализацию в хедер, то все файла, подключившие хедер будут использовать непосредственно значение.

Но! Это не есть хорошо. К примеру, у тебя есть библиотека, в которой есть определение класса Q. Все приложения, использующие эту библиотеку, при компиляции будут подставлять значение вместо статического атрибута. И тут ты решил изменить значение этой константы, для того чтоб изменения вошли в силу - тебе придеться перекомпилировать все приложения, использующие твою либу. (зло?! - воплоти!)

ale ★★
()
Ответ на: комментарий от ale

Да, но на сколько я понимаю, обращение к статическому атрибуту класса занимает определенное количество ресурсов в рантайме в отличие от использование непосредственно значения?

anonymous
()
Ответ на: комментарий от anonymous

можно использовать анонимный enum

class Foo {
public:
enum { C = 0 };
};

тогда значение C будет видимо везде где используется Foo,
и следовательно обращение к 0 как "Foo::C" или просто "0"
будут давать одинаковый по эфективности код.

fghj ★★★★★
()
Ответ на: комментарий от W0wik

А почему если в другом cpp файле написать:

switch(a) { case(Q::C): // ... }

компилятор начинает ругаться: error: `Q::C' cannot appear in a constant-expression

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.