Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/141.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;全局访问类属性时应使用哪种设计模式_C++_Design Patterns_Singleton - Fatal编程技术网

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:我刚刚给出了一个没有编辑构造函数和函数定义的代码段,现在可以编译了。