C++存储全局 std::字符串标签与 getter 和 setter 的策略

C++ strategy for storing global std::string label with getter and setter

本文关键字:getter setter 策略 标签 存储 全局 std 字符串 C++      更新时间:2023-10-16

在我正在从事的一个C++项目中,我需要跟踪一个标签。标签只是存储附加到写入各种文件的结果的std::string,以便结果可以映射到已实现算法的特定阶段

以下是跟踪标签的机制的要求:

  • 所有翻译单元都需要访问此标签
  • 标签必须能够在运行时修改
  • 需要通过吸气/设置器功能控制对标签的访问
  • 始终需要正好 1 个标签

这并不难实现。 但是,尽管如此,我在这里提出这个问题,因为我怀疑这是通常---做的事情,或者至少与通常做的事情非常相似。

我能想到的最好的解决方案是有一个如下类,然后在任何地方都包含接口:

class Label {    
public:
static std::string get();
static int set(std::string s);
private:
static std::string label;
};
std::string Label::get() { return label; }
int Label::set(std::string s) {
if( /* OK to change to "s" */ ) {
label = s;
return 0;
}
return 1;
}
std::string Label::label = "";

因为这些标签中总是只有 1 个,所以似乎应该有比创建类更好的解决方案。 有什么建议吗?

我倾向于怀疑更广泛的类是否可能没有更多用途,例如:

template <class T>
class cond_write {
T val;
std::function<bool()> c;
public:
template <class Cond>
cond_write(T const &t, Cond c): val(t), c(c) {}
cond_write &operator=(T const &t) {
if (c())
val=t;
return *this;
}
operator T() const { return val; }
};

然后,您将使用(在您的情况下)std::string和 lambda 来实例化它,以表示可以发生写入的条件。

而不是getset,你只需分配给它,或将其用作T(在你的例子中是std::string)。例如:

cond_write<std::string> label("Initial label", []() { return whatever(); });
// equivalent to label.set("This might be the new label");
label="This might be the new label";
// equivalent to std::string new_label = label.get();
std::string new_label=label;

我认为这里不需要类,并建议使用自由函数和命名空间。您具有相同的范围语义,但没有所有装饰,例如static。它们还允许您保持内部结构的私密性,就像您在类中一样。一些小的更改,您的代码最终如下所示。

页眉

namespace Label
{    
std::string get();
// only require a copy when necessary and allow rvalues.
int set(const std::string& s); 
};

实现

namespace // unnamed namespace is generally recommended over using static
{
std::string label;
}
std::string Label::get() { return label; }
int Label::set(const std::string& s)
{
if( /* OK to change to "s" */ )
{
label = s;
return 0;
}
return 1;
}