powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Singleton, ошибки линкера
12 сообщений из 12, страница 1 из 1
Singleton, ошибки линкера
    #36853628
Репослав
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый день! Есть простой код:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
class Test
{
	private:
		Test();
	public:
		static Test* test;
		static Test* Instance();
};

Test::Test()
{
}

Test* Test::Instance()
{
	if(!test)
	{
		test = new Test();
	}
	return test;
}

int main(){return false;}

Выдает ошибки:
Код: plaintext
1.
2.
test_singleton.obj : error LNK2001: неразрешенный внешний символ ""public: static class Test * Test::test" (?test@Test@@2PAV1@A)"
D:\Леха\Разработка\vc\projects\test_singleton\Debug\test_singleton.exe : fatal error LNK1120:  1  неразрешенных внешних элементов
В чем может быть проблема?
...
Рейтинг: 0 / 0
Singleton, ошибки линкера
    #36853634
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Репослав,

В .cpp добавьте:
Код: plaintext
Test *Test::test = NULL;
И мембера Test::test в private по идее.
...
Рейтинг: 0 / 0
Singleton, ошибки линкера
    #36853640
Репослав
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Точно, спасибо!
...
Рейтинг: 0 / 0
Singleton, ошибки линкера
    #36853646
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
РепославТочно, спасибо!
Поосторожнее, члены класса всегда нужно инициализировать _явно_. Как и любые переменные. Это не шарп.

Ну кроме статических членов - они по умолчанию ноль. Тут я стат. члена проинициализировал для красоты. Что бы чувство опасности не раздражало при беглом просмотре, оно же глупое. =))
...
Рейтинг: 0 / 0
Singleton, ошибки линкера
    #36853692
Репослав
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
petrav, как так для красоты? Программа ведь без этой инициализации не работает.

З.Ы. Только сейчас понял, что слово "неразрешенный" в ошибке значит не "запрещенный"=) Иногда все-таки лучше нелокализованные продукты=)
...
Рейтинг: 0 / 0
Singleton, ошибки линкера
    #36853745
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Репославpetrav, как так для красоты? Программа ведь без этой инициализации не работает.
В моем коде два пункта:

1. Определение (definition) статической переменной.
2. Инициализация этой переменной.

Но работало бы и так:
Код: plaintext
Test *Test::test;
Без инициализации. Причем с тем же эффектом - потому что статические переменные и так всегда нулевые с начала. В отличие от локальных и в динамической памяти.

Стат. переменную я инициализировал (= NULL) просто так, что бы взгляд не цеплялся за объявление без инициализации.
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
Singleton, ошибки линкера
    #39444091
da17
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Подскажите, столкнулся с похожей проблемой, а для чего нужно снаружи инициализировать статическую переменную, разве в статической ф-ии не происходит ее инициализация?
...
Рейтинг: 0 / 0
Singleton, ошибки линкера
    #39444166
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
da17Подскажите, столкнулся с похожей проблемой, а для чего нужно снаружи инициализировать статическую переменную, разве в статической ф-ии не происходит ее инициализация?

Нужно не инициализировать статическую переменную, а определять её.
(инициализировать при этом вовсе не обязательно).

Дело в том, что строка "объявления" статической переменной в классе является только объявлением (declaration) в смысле С++, но не является определением (definition). Поскольку в С++ (и С) используется модель раздельной компиляции исходных модулей, а заголовок класса может включаться во многие модули, невозможно правильно определить (define) статическую переменную класса в заголовке, это можно сделать только в исходном модуле (.cpp), руками (поскольку компилятору неизвестно в каком именно модуле программист захочет это сделать). Это также должно быть сделано только один раз, иначе будет нарушение ODR.

Это всё предписывается стандартом С++.

P.S. пропустил.

da17Подскажите, столкнулся с похожей проблемой, а для чего нужно снаружи инициализировать статическую переменную, разве в статической ф-ии не происходит ее инициализация?

В статической или какой-то другой функции определение переменной глобальной области видимости (в смысле linkage) (какой является статическая переменная класса) вообще невозможно.
...
Рейтинг: 0 / 0
Singleton, ошибки линкера
    #39444196
da17
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZiv, спасибо. Т.е. я правильно понял, в статической функции мы только ссылаемся на статическую переменную, а определена она уже должна быть заранее?
...
Рейтинг: 0 / 0
Singleton, ошибки линкера
    #39444201
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если хочется вставить инициализацию внутрь класса, то можно так извернуться
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
	struct static_info_t {
		int x = {0};
		double y = {0};
	};

	static static_info_t& si() {
		static static_info_t x;
		return x;
	}


Правда пользоваться не очень красиво получается
Код: plaintext
1.
si().x = 10;
...
Рейтинг: 0 / 0
Singleton, ошибки линкера
    #39444234
da17
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T,
да я что-то предположил, что
Код: sql
1.
2.
3.
4.
if(!test)
{
		test = new Test();
}


тут и происходит инициализация статической переменной test, но видимо был неправ


а что означает это код int a = {0}?
...
Рейтинг: 0 / 0
Singleton, ошибки линкера
    #39444245
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
da17Dima T,
да я что-то предположил, что
Код: sql
1.
2.
3.
4.
if(!test)
{
		test = new Test();
}

тут и происходит инициализация статической переменной test, но видимо был неправ
Неправильно, это при старте проги происходит, т.к. к static public можно обратится не создавая объектов
Код: plaintext
1.
Test::...


da17а что означает это код int a = {0}?
тоже что и
Код: plaintext
1.
int a = 0;


Деталей не помню, разница в ньюансах, в С++11 это ввели.
...
Рейтинг: 0 / 0
12 сообщений из 12, страница 1 из 1
Форумы / C++ [игнор отключен] [закрыт для гостей] / Singleton, ошибки линкера
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]