让我们说我有M,A,B,C类.M是我的应用程序的主要类(这是完成大部分工作的那个)并具有这种结构
class M {
public:
// Something here.
private:
Conifg config;
A a;
std::vector<B> bs;
const C* c;
};
在一个主要内容中,我创建了一个M类的实例m,我想设置我的配置对象,比如从文件中读取它。配置对象没什么特别的,它可以是协议缓冲区或简单的结构。
现在,我希望a,b和c能够访问配置对象,因为它们需要一些全局设置。这些设置是全局的,它们不会改变,并且对于A,B和C(和M)的每个实例都是相同的。我目前正在做的是在每个类A,B和C中都有一个静态字段,我正在为这些类的每个实例设置一个配置对象的副本。我不希望这些类知道M.的存在。这是最好的解决方案吗?我是否应该考虑全局配置变量?
答案 0 :(得分:9)
只需将Config对象传递给A,B和C构造函数(具体而言,将引用传递给存储在M中的Config对象。
这会给你:
但无论你做什么,don't use a singleton,并试图避免一般的静态/全局数据。
答案 1 :(得分:4)
我建议您使用额外的静态类进行配置,而不是在所有类中使用静态字段,其中将标题包含在您想要的位置。
实现一个静态构造函数,在其中初始化静态成员中所需的所有数据。我认为这将是一个更好的解决方案。
答案 2 :(得分:4)
我个人宁愿以某种方式将该配置对象传递给A B C而不是使用全局/静态对象。 在构建b c时将它(它的引用)作为参数传递,或者稍后通过set_config()调用设置它?
答案 3 :(得分:3)
我发现这些问题的可维护解决方案最多,都是使用静态函数。如果使用某个对象接口,请将其隐藏在这些功能后面。
这是一个例子。
namespace config {
// public interface that is used a lot
bool GetConfigValue(const std::string &key, std::string &val);
}
namespace config {
namespace detail {
// detail interface that is used for setup and tear down
class Config {
public:
virtual ~Config() {}
virtual bool get(const std::string &key, std::string &val) = 0;
};
void RegisterConfig(Config *cfg);
void ResetConfig();
}}
老实说,你最终必须改变界面,而且它会很糟糕。您在整个代码中暴露的越多,风险就越高。所以保持简单。
作为背景,这是一个cross-cutting concern,通常很难处理。你真的不想把这些东西传递给你的对象。面向方面编程的研究可能很有趣,因为他们经常谈论这个主题。