gpt4 book ai didi

c++ - 返回析构函数有副作用的对象

转载 作者:行者123 更新时间:2023-11-28 01:24:16 26 4
gpt4 key购买 nike

我们有一个类可以帮助我们将数据发送到 telegraf/influxdb(即用于监控)。它看起来大致是这样的:

class TelegrafSend {
public:
// // Constructor does some default stuff based on binary name and context.
TelegrafSend();
// Destructor sends the object.
~TelegrafSend();
// Exists in a couple variants. Probably could have been a template.
void AddTag(const std::string& tag_name, const std::string& tag_value);
// Same.
void AddField(const std::string& field_name, const int field_value);
};

为了清楚起见,它看起来像这样:

TelegrafSend TelegrafSend::AddField(const string& field_name, const int field_value) {
fields_[field_name] = to_string(field_value);
sent_ = false;
return *this;
}

这很管用:

TelegrafSend telegraf;
telegraf.AddTag("a_tag", "a_value");
telegraf.AddField(kTelegrafCount, 1);

当它超出范围时,它会被发送,这是一个很好的行为,因为一个函数可以在它执行时添加几个指标,并且函数的所有退出都会导致对象发送。

现在我有了一个聪明的主意:

class TelegrafSend {
public:
// // Constructor does some default stuff based on binary name and context.
TelegrafSend();
// Destructor sends the object.
~TelegrafSend();
// Exists in a couple variants. Probably could have been a template.
TelegrafSend AddTag(const std::string& tag_name, const std::string& tag_value);
// Same.
TelegrafSend AddField(const std::string& field_name, const int field_value);
};

所以我可以写

TelegrafSend telegraf.AddTag("a_tag", "a_value").AddField(kTelegrafCount, 1);

这里的问题是我正在创建临时文件,所以虽然这最终有效,但每次返回都会创建一个临时文件,该临时文件会被销毁并发送到 telegraf。这对于 influxdb 来说真的很低效,甚至不谈 C++ 中的不良做法。

我已经尝试了一些关于返回右值引用的变体,但要么我尝试返回对临时变量或堆栈变量的引用,要么我做了同样愚蠢的事情。我在生产环境中发现的示例还做了很多其他事情,以至于我不确定该怎么做。

有任何指向此模式最佳实践的指示吗?还是我试图做一些我不应该做的句法?

最佳答案

您必须在这些方法中返回对自身的引用,而不是创建新对象。
也可以考虑实现移动构造函数。

class TelegrafSend {
public:
TelegrafSend();
~TelegrafSend();
TelegrafSend(const TelegrafSend&) = delete;
TelegrafSend& operator = (const TelegrafSend&) = delete;
TelegrafSend(TelegrafSend&&); // possibly = delete;
TelegrafSend& operator = (TelegrafSend&&); // possibly = delete;

// Exists in a couple variants. Probably could have been a template.
TelegrafSend& AddTag(const std::string& tag_name, const std::string& tag_value)
{
/*..*/
return *this;
}
// Same.
TelegrafSend& AddField(const std::string& field_name, const int field_value)
{
/*..*/
return *this;
}

};

然后你可以使用:

TelegrafSend{}.AddTag("a_tag", "a_value").AddField(kTelegrafCount, 1);

关于c++ - 返回析构函数有副作用的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54687783/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com