C ++将长字符串传递给构造函数或setter

时间:2013-02-12 15:57:29

标签: c++ c++11 parameter-passing glib stdstring

我有一个带有Glib :: ustring成员的类(如果你不熟悉它,假设它是std :: string),它应该包含一个长字符串,即至少一段,也许还有一段。甚至可能超过10个段落。该字符串计划显示在GUI中,因此将来它可能会存储在文本小部件的缓冲区中,但是现在它只是我的C ++类的字符串成员对象。

问题是:如何将字符串传递给构造函数,以及如何将其传递给set_string()setter方法。长字符串意味着一个大的副本,所以我虽然一个很好的解决方案是采用rvalue引用和std ::将参数移动到成员对象中。但我也不希望类接口令人惊讶并难以使用/理解。你知道,最不惊讶的规则。

所以我在想,在这种情况下,预期/通用解决方案是什么?

(对于setter方法,这里是另一个选项:由于编辑是在GUI中完成的,只需让GUI直接编辑字符串,然后唯一使用setter方法就是以编程方式完全替换字符串,例如重置或撤消最近的编辑)

class MyClass
{
public:
     explicit MyClass (Glib::ustring str);
     void set_string (Glib::ustring str);
private:
     Glib::ustring str;
}

(我已经看过现有库的代码,例如gtkmm,通过const引用获取字符串,但我也看到了SO帖子的答案,说明了传值,以便进行优化)

2 个答案:

答案 0 :(得分:4)

http://cpp-next.com/archive/2009/08/want-speed-pass-by-value/

假设string具有高效的移动构造函数,您的函数应该按string的值。

当您希望字符串很长时,调用者会调用std::move并将值传递给setter / constructor。这并不奇怪,因为std::move非常清楚地表明您正在移动数据。

如果你的系统只有少量的并发性,并且你很少修改字符串(实际上,大多数字符串的共享远远超过它们的修改),指向不可变字符串的共享指针实际上是一个非常有用的模式。 (共享写入数据是引用计数,因此高并发性可能会导致争用)

答案 1 :(得分:1)

我会去参考(不仅传递它们而且还存储引用)。但是,设定者必须重新安置参考,这是不可能的。如果你真的需要在构造之后更改字符串,你必须使用指针(可能是智能指针)。

根据周围的代码,您可能希望使用字符串的共享所有权。在这种情况下,我会使用std::shared_pointer<GLib::ustring>如果您需要setter 。 (否则,参考更好。)

请注意,“某些段落”不是很长的字符串。在用户界面中,加载一些文本文件时,几毫秒的延迟是完全可以接受的。一如既往:请首先分析您的代码,检测瓶颈,然后优化,如果您需要它更快。