Я пишу программу на QT, которая в настоящее время имеет GameEngine
класс и MainWindow
учебный класс.
GameEngine.h:
#include "Player.h"
class GameEngine : public QObject
{
Q_OBJECT
public:
void test();
signals:
void newPlayerDataReady(const std::vector<Player>* playerList);
private:
std::vector<Player> mPlayers; // List of player objects
}
GameEngine.cpp
#include "GameEngine.h"
// Omitting constructor and destructor for simplicity of the example
void GameEngine::test() {
emit newPlayerDataReady(&mPlayers);
}
GameEngine
хранит большое количество данных в массиве экземпляров Player (Player является довольно сложным классом с большим количеством различных членов), который должен храниться там для централизации логики программы (короче говоря).
MainWindow
класс GUI, который должен визуализировать данные, когда сигнал newPlayerDataReady
излучается и представляет большую часть данных на графике, в списке и т. д. Это делается путем подключения сигнала к выделенному слоту в MainWindow
учебный класс. Соединение создается в Main.cpp, который владеет экземпляром обоих классов.
Итак, мой вопрос:
Если я хочу передать все эти данные из одного класса в другой, не позволяя получателю изменять данные (доступ только для чтения), есть ли более распространенная практика, чем использовать постоянные указатели на данные?
Это не то, что мне не нравится это решение. Я просто хочу быть абсолютно уверенным, что я делаю это правильно с самого начала вместо того, чтобы переделывать много позже в процессе.
Я знаю, что можно было бы сделать одну альтернативу для обмена данными в виде копий частного члена, но я не думаю, что это было бы гладким решением, так как объем данных увеличится до такой степени, что это может повлиять на скорость программа.
Итак, мой вопрос: если я хочу поделиться всеми этими данными из одного класса в другой, не позволяя получателю изменять данные (доступ только для чтения), существует ли более распространенная практика для этого, чем использование постоянных указателей на данные?
Обмен через константные указатели — это нормально, хотя обмен константной ссылкой (т.е. const std::vector<Player> &
) может быть немного более предпочтительным, хотя бы потому, что любой код, получающий const-ссылку, может быть на 100% уверен, что любая полученная ссылка не NULL, поскольку ссылки NULL не разрешены языком (тогда как указатели NULL разрешены).
Еще одна вещь, которую следует учитывать, — это проблемы времени жизни объекта, т. Е. Если вы передадите const std::vector<Player>*
на ваш MainWindow
класс, а MainWindow
класс хранит копию этого значения-указателя (т.е. копирует переданный указатель в локальную переменную-член), а затем вектор уничтожается, MainWindow
останется с висящим указателем, который вызовет неопределенное поведение (то есть, возможно, сбой или, что еще хуже, незаметно повредит пространство памяти вашей программы каким-либо очень сложным для отладки способом), если / когда он когда-либо попытается разыменовать указатель. Если вы хотите избежать какой-либо возможности этого конкретного фиаско, вы можете вместо этого передать данные через смарт-указатель (т.е. shared_ptr, или если вы предпочитаете использовать специфичные для Qt API, QSharedPointer или QPointer объект)
Других решений пока нет …