C ++全局访问类属性时应使用哪种设计模式

时间:2018-02-11 05:11:42

标签: c++ design-patterns singleton

问题很简单。目前我正在开发一个有类的项目,可以调用它ResoureceHandler.cpp。这个类有一些属性,其余类需要这些方法。一些属性,如用户名,我可以获得的用户ID,只需通过调用resourceHandler->getUserName()设置,反之亦然。我可以想到两种方式

方法1:使类单例并访问方法get,set。

方法2 使类和属性保持静态,无需访问它们 任何实例。

但我不确定其中任何一个都属于正确的设计。什么应该是解决这类问题的理想方式?

2 个答案:

答案 0 :(得分:1)

好吧,如果你想要一些高性能的东西。使用两种方法中的任何一种。

但是如果你想要像其他语言一样的良好编码习惯。你可以尝试这样的事情:

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;
}

为什么这一切?

如果有一个冗长的用户相关操作,你突然改变currentUser。作为一个shared_ptr,这使得它在操作中仍未释放和未突变,而静态变量将引用新的。另一种方法是使用复制,但在C ++中它可能会导致一些性能问题。

答案 1 :(得分:1)

而是建议第三种方法。避免使用全局变量或单例。干净的代码应该是关键。必要时使用辅助函数和类似名称空间。如果您的类很复杂,请使用代理设计模式来降低类对象的复杂性以及更简洁的代码。

// foo.h(避免自己实例化foo类)

namespace myproject { namespace part1
  {
    class foo  
    {
       string username_;
      public: 
       foo() { username_ = "foo";}
      //properties
         string get_username() const { return username_; }
      //methods
    };    

// helper functions 

  string get_username();

 }    
}

// 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();
   }
  }
}

// poo.h

namespace myproject { namespace part2
  {
    class poo  
    {
       string username_;
      public: 
         poo(){ username_ = "poo";}
      //properties
         string get_username() const {return username_;}
      //methods
    };


// helper functions 

  string get_username();

 }    
}

的main.cpp

using namespace myproject;
int main()
{
  cout << part1::get_username() << endl;
  auto str2 = part2::get_username();
  return 0;
}