Russian Qt Forum

Программирование => С/C++ => Тема начата: blood_shadow от Сентябрь 22, 2010, 22:59



Название: Проблема с статической переменной
Отправлено: blood_shadow от Сентябрь 22, 2010, 22:59
Есть хэдер(mainwindow.h), в котором объявлена статическая переменная recentFiles

Код:

#include <QMainWindow>


class QAction;
class QLabel;
class FindDialog;
class Spreadsheet;

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow();
    static QStringList recentFiles;

protected:
    void closeEvent(QCloseEvent *event);

};

QStringList MainWindow::recentFiles;


этот хэдер подключается в файл mainwindow.cpp и main.cpp, но проэкт не компилируется сборщик выдает следуещее:
Код:
./release\mainwindow.o:mainwindow.cpp:(.bss+0x0): multiple definition of `MainWindow::recentFiles' 
./release\main.o:main.cpp:(.bss+0x0): first defined here
./release\moc_mainwindow.o:moc_mainwindow.cpp:(.bss+0x0): multiple definition of `MainWindow::recentFiles'
./release\main.o:main.cpp:(.bss+0x0): first defined here
collect2: ld returned 1 exit status
mingw32-make[1]: *** [release\spreadsheet.exe] Error 1
mingw32-make: *** [release] Error 2
Процесс "C:/Program_Files/Qt/2010.02/mingw/bin/mingw32-make.exe" завершился с кодом %2.
Ошибка сборки проекта spreadsheet (цель: Настольный компьютер)
Во время выполнения сборки на этапе "Сборка"

Из этого я понял что при подключении хэдера в два файла, делается попытка создать два екземпляра переменной recentFiles, что делать нельзя, как поступить в этой ситуации если я хочу использовать эту статическую переменную?


Название: Re: Проблема с статической переменной
Отправлено: lit-uriy от Сентябрь 23, 2010, 06:23
1) статическую переменную нужно инициализировать значением.
2) определение и инициализация должны находится в cpp-файле, а в заголовочном только объявление


Название: Re: Проблема с статической переменной
Отправлено: Авварон от Сентябрь 23, 2010, 08:30
иногда спасает слово const у статик переменной (если она может быть константной, но, очевидно, это не ваш случай)


Название: Re: Проблема с статической переменной
Отправлено: blood_shadow от Сентябрь 23, 2010, 23:38
1) статическую переменную нужно инициализировать значением.
2) определение и инициализация должны находится в cpp-файле, а в заголовочном только объявление
Спасибо помогло, наконец-то понял зачем второй раз объявлять статическую переменную :)
еще вопрос - разве обязательно ее сразу же инициализировать, вот в книге Шилдта написано что все статические переменные инициализируются нулем еще до создания объекта?


Название: Re: Проблема с статической переменной
Отправлено: Alex Custov от Сентябрь 24, 2010, 04:44
1) статическую переменную нужно инициализировать значением.
2) определение и инициализация должны находится в cpp-файле, а в заголовочном только объявление
Спасибо помогло, наконец-то понял зачем второй раз объявлять статическую переменную :)
еще вопрос - разве обязательно ее сразу же инициализировать, вот в книге Шилдта написано что все статические переменные инициализируются нулем еще до создания объекта?

первый раз ты делаешь declaration, намёк на то, что в классе будет одна общая переменная для всех объектов. Эту переменную потом нужно явно создать (definition), и только один раз, иначе будут ошибки линковки.

По стандарту (3.6.2) статические члены инициализируются нулём перед любой другой инициализацией.


Название: Re: Проблема с статической переменной
Отправлено: lit-uriy от Сентябрь 24, 2010, 07:27
ну QStringList нулём инициализировать не получится.
Я себе за правило такое взял: так как не у всех классов есть открытый конструктор по умолчанию, то лучше инициализировать самому. Чтоб знать с чего всё началось.


Название: Re: Проблема с статической переменной
Отправлено: Alex Custov от Сентябрь 24, 2010, 19:32
ну QStringList нулём инициализировать не получится.

там не совсем инициализация, там написано, что место под статический объект заполняется нулями.


Название: Re: Проблема с статической переменной
Отправлено: blood_shadow от Октябрь 25, 2010, 20:53
1) статическую переменную нужно инициализировать значением.
2) определение и инициализация должны находится в cpp-файле, а в заголовочном только объявление
a стало интересно, а можно допустим сделать статической переменную QString? как для нее и когда выделять память?


Название: Re: Проблема с статической переменной
Отправлено: Igors от Октябрь 25, 2010, 21:16
a стало интересно, а можно допустим сделать статической переменную QString? как для нее и когда выделять память?
Ну лучше спросить кто и когда для нее выделяет память? Это делает "невидимый" который вызывается еще до ф-ции main для инициализации всех static объектов. В разных компиляторах он называется по-разному, типа CRT_Init. А вообще желание "докопаться" - большой плюс (хотя неизвестно во что оно вольется  :)) 


Название: Re: Проблема с статической переменной
Отправлено: blood_shadow от Октябрь 25, 2010, 21:30
a стало интересно, а можно допустим сделать статической переменную QString? как для нее и когда выделять память?
Ну лучше спросить кто и когда для нее выделяет память? Это делает "невидимый" который вызывается еще до ф-ции main для инициализации всех static объектов. В разных компиляторах он называется по-разному, типа CRT_Init. А вообще желание "докопаться" - большой плюс (хотя неизвестно во что оно вольется  :)) 
а можете тогда указать где почитать инфу про данный процесс или хотя бы где искать?


Название: Re: Проблема с статической переменной
Отправлено: Igors от Октябрь 26, 2010, 11:50
а можете тогда указать где почитать инфу про данный процесс или хотя бы где искать?
Просто соорудите какой-нибудь класс и поставьте точку останова в его конструкторе. Объявите static экземпляр этого класса - ну и смотрите в отладчике что и как.