按值传递还是按引用传递C++字符串

27

我想知道在传递时,C++字符串是否足够小,以至于通过值传递比通过引用传递更有效率。


为什么?也就是说,你希望通过这个知识获得什么成就? - wallyk
可能是重复问题:https://dev59.com/AnI_5IYBdhLWcg3wAeLl - Kirill V. Lyadvinsky
虽然它涉及时间旅行,但我认为现在应该将其标记为Are the days of passing const std::string & as a parameter over?的重复内容,这是关于现代C++中此问题的规范讨论。 - underscore_d
2个回答

35
不要。通过引用传递它:
void foo(const std::string& pString);

通常情况下,如果一个对象有一个非平凡的复制构造函数,则通过引用传递该对象,否则通过值传递。

字符串通常由指向数据的指针和长度计数器组成。它可能包含更多或更少,因为它是实现定义的,但很不可能你的实现只使用一个指针。

在模板代码中,你可以使用const T&,因为函数定义将可供编译器使用。这意味着它可以决定是否应该为你使用引用(我认为)。


5
你的启发式算法不能用于doublelong double类型的数据(通常最好通过值传递)。此外,对于单参数函数,通常最好通过值传递2个机器字长的用户自定义类型(UDT),因为寄存器将用于存储两个部分(并节省额外的间接引用)。 - Pavel Minaev
4
此外,sizeof(T)通常是一种非常糟糕的度量方式,因为它并不能测量将要被复制的数据的真实大小。以string为例,如果使用一个简单的指向数据的指针表示,则sizeof(string)通常只会是sizeof(void*);或者在实现短字符串优化时可能会占用两个或三个字长。但是,当你复制一个字符串时,它的复制构造函数将会复制指向的数据,这是未计算在内的。vector等情况也是如此。 - Pavel Minaev
4
我个人更偏向于以下的启发式方法:对于内置类型按值传递,对于任何具有复制构造函数的类型按const引用传递。 - Matthieu M.
@GMan: :D ...不幸的是它没有考虑到“传值”优化,这可以帮助编译器避免副本...虽然很难知道它何时会启动:/ - Matthieu M.

3

当然不是。除非您的特定实现具有写时复制语义(由于线程问题,这种情况很少见),否则在按值传递字符串时必须复制整个字符串(即使实际字符串数据存储在堆上)。即使字符串对象本身在内部只有几个指针,要复制的数据量也与字符串长度成正比。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接