I am writing a program in QT, which currently has a GameEngine
class and a MainWindow
class.
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);
}
The GameEngine
is storing a lot of data in the array of Player instances (Player is a rather complex class itself with a lot of different members), which has to be stored there for centralizing the logic of the program (long-story short).
The MainWindow
is a GUI class, which is supposed to visualize the data, when the signal newPlayerDataReady
is emitted and represent a lot of the data on a graph, a list etc. This is done by connecting the signal to a dedicated slot in the MainWindow
class. The connection is created in Main.cpp, which owns the instance of both classes.
So, my question is: If I want to share all this data from one class to another without letting the receiver alter the data (read-only access), is there a better common practice to do this, rather than using constant pointers to the data?
It is not that I don't like this solution. I just want to be absolutely sure that I doing it right from the beginning instead of having to rework a lot later in the process.
I know that one alternative could be done exchange the data as copies of the private member, but I don't think it would be a smooth solution, as the amount of data will increase to a point, where it might affect the speed of the program.
So, my question is: If I want to share all this data from one class to another without letting the receiver alter the data (read-only access), is there a better common practice to do this, rather than using constant pointers to the data?
Sharing via const-pointers is fine, although sharing a const-reference (i.e. const std::vector<Player> &
) might be very slightly preferable, if only because any code receiving a const-reference can be 100% assured that any reference it receives isn't NULL, since NULL references aren't allowed by the language (whereas NULL pointers are allowed).
One other thing to consider is object-lifetime issues -- i.e. if you pass a const std::vector<Player>*
to your MainWindow
class, and the MainWindow
class keeps a copy of that pointer-value (i.e. copies the passed-in pointer to a local member-variable), and then the vector is destructed, the MainWindow
will be left holding a dangling pointer that will invoke undefined behavior (i.e. probably crash, or worse, silently corrupt your program's memory space in some very-hard-to-debug fashion) if/when it ever tries to dereference the pointer. If you want to avoid any possibility of that particular fiasco, you can pass the data via a smart-pointer instead (i.e. either a shared_ptr, or if you prefer to use the Qt-specific APIs, a QSharedPointer or QPointer object)