Well, if you want something high performance. Use either of the two methods.
But if you want good coding practice like other languages. You can try something like this:
class User {
private:
int id;
string name;
public:
User(int id, const string &name): id(id), name(name) {}
inline int getId() const { return id; }
inline const string &getName() const { return name; }
// Make a shared object of the User class
static shared_ptr<User> currentUser;
static inline void logIn(int id, const string &name) {
User::currentUser = std::make_shared<User>(id, name);
}
};
shared_ptr<User> User::currentUser = 0;
void doSomethingLengthyWithUser(shared_ptr<User> user) {
static mutex mut; // The lock, for printing
// Simulate long running process
std::this_thread::sleep_for(std::chrono::milliseconds(3000));
// This (lock block) is only to make the printed output consistent
// Try to remove the block, and use the "cout" line only, and see.
{
lock_guard<mutex> l(mut);
cout << "Done it with: " << user->getName() << endl;
}
}
int main() {
// Login first user
User::logIn(1, "first");
cout << "Logged in: " << User::currentUser->getName() << endl;
// Now, we want to do something lengthy with the current user.
// If you were in a different class, you could use the static variable
std::thread doWithFirst(doSomethingLengthyWithUser, User::currentUser);
// Login the second user
User::logIn(2, "second");
cout << "Logged in: " << User::currentUser->getName() << endl;
// Do the lengthy operation with the second also
std::thread doWithSecond(doSomethingLengthyWithUser, User::currentUser);
// Wait for the second thread to end;
doWithSecond.join();
return 0;
}
Why all this?
If there was a lengthy user-related operation, and you suddenly mutate the currentUser. Being a shared_ptr this makes it still unreleased and unmutated INSIDE THE OPERATION, while the static variable will refer to the new one. Also an alternative approach is using copying, but in C++ it may cause some performance problem.