C++ C++;全局访问类属性时应使用哪种设计模式
问题很简单。目前我正在从事一个项目,该项目有一个类,我们称之为C++ C++;全局访问类属性时应使用哪种设计模式,c++,design-patterns,singleton,C++,Design Patterns,Singleton,问题很简单。目前我正在从事一个项目,该项目有一个类,我们称之为resourceHandler.cpp。这个类有一些属性和方法,其余的类都需要这些属性和方法。我可以通过调用resourceHandler->getUserName()设置一些属性,如username和userid,反之亦然。我可以想出两种方法 方法1:将类设为singleton并访问要获取、设置的方法 方法2将类和属性设置为静态,并在不使用 任何情况 但我不确定它们是否符合正确的设计。解决这类问题的理想方法应该是什么 如果你想要高性
resourceHandler.cpp
。这个类有一些属性和方法,其余的类都需要这些属性和方法。我可以通过调用resourceHandler->getUserName()
设置一些属性,如username和userid,反之亦然。我可以想出两种方法
方法1:将类设为singleton并访问要获取、设置的方法
方法2将类和属性设置为静态,并在不使用
任何情况
但我不确定它们是否符合正确的设计。解决这类问题的理想方法应该是什么 如果你想要高性能的东西。使用这两种方法之一 但是,如果您想像其他语言一样获得良好的编码实践。您可以尝试以下方法:
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;
}
类用户{
私人:
int-id;
字符串名;
公众:
用户(int-id、const-string和name):id(id)、name(name){}
内联int getId()常量{return id;}
内联常量字符串&getName()常量{return name;}
//创建用户类的共享对象
静态共享用户;
静态内联无效登录(int-id、const-string和name){
User::currentUser=std::使_共享(id,name);
}
};
共享用户::currentUser=0;
void doSomethingLengthyWithUser(共享用户){
静态互斥mut;//锁,用于打印
//模拟长时间运行的过程
std::this_线程::sleep_for(std::chrono::毫秒(3000));
//此(锁定块)仅用于使打印输出一致
//尝试移除块,仅使用“cout”行,然后查看。
{
锁紧护罩l(mut);
如果你想要高性能的东西,可以使用这两种方法中的任何一种
但是,如果您想像其他语言一样获得良好的编码实践,您可以尝试以下方法:
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;
}
类用户{
私人:
int-id;
字符串名;
公众:
用户(int-id、const-string和name):id(id)、name(name){}
内联int getId()常量{return id;}
内联常量字符串&getName()常量{return name;}
//创建用户类的共享对象
静态共享用户;
静态内联无效登录(int-id、const-string和name){
User::currentUser=std::使_共享(id,name);
}
};
共享用户::currentUser=0;
void doSomethingLengthyWithUser(共享用户){
静态互斥mut;//锁,用于打印
//模拟长时间运行的过程
std::this_线程::sleep_for(std::chrono::毫秒(3000));
//此(锁定块)仅用于使打印输出一致
//尝试移除块,仅使用“cout”行,然后查看。
{
锁紧护罩l(mut);
建议使用第三种方法。避免使用全局变量或单例。一个干净的代码应该是关键。必要时使用辅助函数和类似的名称空间。如果您的类很复杂,请使用代理设计模式来降低类对象的复杂性,并获得更干净的代码
//h(避免自己实例化foo类)
//foo.cpp
namespace myproject { namespace part1
{
shared_ptr<foo>& get_foo()
{
static shared_ptr<foo> pt;
if( pt == nullptr)
pt = make_shared<foo>();
return pt;
}
string get_username()
{
return get_foo()->get_username();
}
}
}
main.cpp
using namespace myproject;
int main()
{
cout << part1::get_username() << endl;
auto str2 = part2::get_username();
return 0;
}
使用名称空间myproject;
int main()
{
建议使用第三种方法。避免使用全局变量或单例。一个干净的代码应该是关键。必要时使用辅助函数和类似的名称空间。如果您的类很复杂,请使用代理设计模式来降低类对象的复杂性,并获得更干净的代码
//h(避免自己实例化foo类)
//foo.cpp
namespace myproject { namespace part1
{
shared_ptr<foo>& get_foo()
{
static shared_ptr<foo> pt;
if( pt == nullptr)
pt = make_shared<foo>();
return pt;
}
string get_username()
{
return get_foo()->get_username();
}
}
}
main.cpp
using namespace myproject;
int main()
{
cout << part1::get_username() << endl;
auto str2 = part2::get_username();
return 0;
}
使用名称空间myproject;
int main()
{
不可能重复的应该避免可变全局状态。如果您选择,可以使用简单的全局变量。如果您需要线程安全并控制初始化顺序,则使用Scott Meyer的单例。可能重复的应该避免可变全局状态。如果您选择,可以使用简单的全局变量。如果您需要线程安全并控制初始化顺序,那么请使用Scott Meyer的Singleton。我忘了说此代码必须至少使用C++11标准编译。因为“std::thread”,需要移动构造函数。我忘了说此代码必须至少使用C++11标准编译。因为“std::thread”,需要移动构造函数。你能编译上面的代码吗?我在使用getter时遇到编译错误“非法调用非静态成员函数”method@sujat:我刚刚给出了一个没有编辑构造函数和函数定义的代码段,它现在可以编译了。你能编译上面的代码吗?我得到编译错误“使用getter时非法调用“非静态成员函数”method@sujat:我刚刚给出了一个没有编辑构造函数和函数定义的代码段,现在可以编译了。