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

C++ Passing a long string to constructor or setter

本文关键字:构造函数 setter 字符串 C++      更新时间:2023-10-16

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

问题是:如何将字符串传递给构造函数,以及如何将其传递给set_string()setter方法。一个长字符串意味着一个大的副本,所以我认为一个好的解决方案是获取一个右值引用并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帖子的答案是通过值传递以允许优化)

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

假设string有一个有效的move构造函数,那么函数应该按值取string

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

如果您的系统只有适度的并发性,并且您很少修改字符串(实际上,大多数字符串的共享量远大于修改量),那么指向不可变字符串的共享指针实际上是一种非常有用的模式。(共享写入数据是引用计数,因此高并发级别可能会导致争用)

我会寻找引用(不仅传递引用,还存储引用)。然而,setter必须重新放置引用,这是不可能的。如果在构造后确实需要更改字符串,则必须使用指针(可能是智能指针)。

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

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