powered by simpleCommunicator - 2.0.28     © 2024 Programmizd 02
Map
Форумы / C++ [игнор отключен] [закрыт для гостей] / Глобальные объекты в VCL
10 сообщений из 10, страница 1 из 1
Глобальные объекты в VCL
    #40084277
DmitryBykov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Здравствуйте.
Вынужден переходить с C# VS на С++ Builder. И возникла такая сложность.

Хочу создать приложение VCL и при этом часть рабочих объектов не привязывать к формам. То есть сделать их не полями класса формы, а глобальными (ну или полями одного глобального объекта). Объекты будут существовать всё время работы приложения.

Делаю примерно так

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
class Tconfig
{
	public:
	int a;
	void Load();
	int GetPar();
};

void Tconfig::Load()
{
	this->a = 10;
}

int Tconfig::GetPar()
{
	return this->a;
}

Tconfig config;

void Init()
{
  config.Load();
}


//---------------------------------------------------------------------------
int WINAPI _tWinMain(HINSTANCE, HINSTANCE, LPTSTR, int)
{
	try
	{
		Application->Initialize();
		Application->MainFormOnTaskBar = true;
		Application->CreateForm(__classid(TForm1), &Form1);

		Init();

                auto aa = config.GetPar(); // aa = 10

		Application->Run();
	}
	catch (Exception &exception)
	{
		Application->ShowException(&exception);
	}
	catch (...)
	{
		try
		{
			throw Exception("");
		}
		catch (Exception &exception)
		{
			Application->ShowException(&exception);
		}
	}
	return 0;
}




Процедура Init должна инициализировать объекты: считывать из файлов конфигурации и заполнять данными. Тут пока всё работает.

Далее пробую использовать объект с формы. Для теста делаю это с таймером.

Код: plaintext
1.
2.
3.
4.
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
	Label1->Caption = std::to_string(config.GetPar()).c_str();
}



И вот тут засада. Label1->Caption выдаёт 0, хотя выше была инициация с a=10. Начинаю отладку и выясняется, что до и после вызова Application->Run() в config разные объекты (разные указатели). То есть за это время С++ пересоздал объект и моя инициация пропала.
Что тут лучше сделать?
Если засунуть Init в FormActivate, то всё работает. Но я не хочу привязываться к форме. Тем более, может получиться, что приложение стартует со скрытой формой. FormCreate и конструктор формы вызываются до Application->Run() .
Быть может можно как-то вызвать код после Application->Run() , но без формы?
Боюсь, что даже если я создам объект параллельного потока для инициализации, то этот объект тоже может не дожить до нужного момента.

Есть конечно кривые методы. Как то:
Делать постоянные проверки, была ли инициализация при вызове методов объекта или делать те же самые проверки снаружи по таймеру.
Но это как-то плохой тон.

Кстати, интересная особенность, отладчик всегда отображает первый (правильный) вариант объекта, но данные всё равно выдаются неправильные. И только если запросить указатель объекта, окажется, что указатель-то уже не тот.
...
Рейтинг: 0 / 0
Глобальные объекты в VCL
    #40084279
Siemargl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DmitryBykov

...
Что тут лучше сделать?
...

1. Выучить С++93.
2. Выучить VCL.

Пример не воспроизводит ошибку.
...
Рейтинг: 0 / 0
Глобальные объекты в VCL
    #40084281
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SiemarglПример не воспроизводит ошибку.

Телепаю: первый кусок кода у него в заголовке.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Глобальные объекты в VCL
    #40084282
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Выносишь определение класса в .hpp файл.
Подключаешь (#include) этот файл в каждый .cpp в котором надо работать с твоим глобальным объектом.
В одном (обычно это main.cpp) делаешь
Код: plaintext
1.
  TConfig config;

Во всех остальных .cpp (или прямо в .hpp с определением класса) делаешь
Код: plaintext
1.
  extern TConfig config;

Инициализацию объекта делаешь при старте приложения (как ты уже сам показал).

Все.

Есть и еще варианты (inline например который обсуждали тут не так давно посмотри старые топики), но работа с extern это классический подход поддерживаемый всеми компиляторами и учебниками, а не только новейшими.
...
Рейтинг: 0 / 0
Глобальные объекты в VCL
    #40084285
DmitryBykov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Siemargl

1. Выучить С++93.
2. Выучить VCL.


Это понятно. Вот и учу. На практике.

Siemargl

Пример не воспроизводит ошибку.


Возможно по неопытности в С++ я не там ошибку ищу.
Извините, но в С# я привык, что одно объявление объекта даёт один объект, который я сам создаю и уничтожаю. Здесь же это пытаются сделать за меня.

Если я вызываю config->Load из любого события формы (из Activate, Create или конструктора), то всё работает, a = 10.
Если же пытаюсь выполнить config->Load вне формы, в другом файле, то при обращении к объекту в методах (событиях) формы, мне выдают уже другой объект, не инициализированный. И мне трудно понять, почему объявленная единожды переменная имеет разные значения в разном контексте её использования.

как бы получается, что на форму у меня будут идти одни значения, а при вызове объекта откуда-то ещё (допустим, из других потоков) - значения будут уже другие.
...
Рейтинг: 0 / 0
Глобальные объекты в VCL
    #40084286
DmitryBykov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
White Owl,

Спасибо. Не думал как-то что расположение кода как-то влияет.

У меня код-описание располагался в одном из файлов .cpp, а другой на него (на cpp) ссылался в include. И даже не нужный в том коде extern прописан был.

Теперь вынес код в отдельный файл и вроде как один объект остался.
...
Рейтинг: 0 / 0
Глобальные объекты в VCL
    #40084290
PetroNotC Sharp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DmitryBykov,
По архитектуре.
Ничего страшного если ты будешь создавать объекты по мере надобности.
Преждевременная оптимизация - зло.
...
Рейтинг: 0 / 0
Глобальные объекты в VCL
    #40084320
Фотография NekZ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Пора уже на модули переходить, инклуды для дедов.
...
Рейтинг: 0 / 0
Глобальные объекты в VCL
    #40084324
Фотография ну я
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DmitryBykov,

Кажется, тут будет хорошо выглядеть автосоздаваемый DataModule.
...
Рейтинг: 0 / 0
Глобальные объекты в VCL
    #40084345
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NekZПора уже на модули переходить, инклуды для дедов.

То есть ты советуешь аффтару возвращаться на Ц-шарп и не пытаться прыгать выше головы.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
10 сообщений из 10, страница 1 из 1
Форумы / C++ [игнор отключен] [закрыт для гостей] / Глобальные объекты в VCL
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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