我应该如何将std :: string传递给函数?

nak*_*iya 14 c++

我是否应该总是通过const引用将std :: string传递给函数,如果在该函数内完成的所有内容都是复制该字符串?另外,传递值和通过引用传递之间的差异(性能或其他)是什么?据我所知,一个使用operator=和另一个复制构造函数.是这样的吗?

Joh*_*ski 29

不要相信你在网上看到的一切.传递const引用更好.为了证明,我写了一个测试程序......

TEST.CPP:

#include <ctime>
#include <iostream>
#include <string>

void foo(std::string s);
void bar(const std::string& s);

int main() {
    const std::string s("test string");

    clock_t start = clock();
    for (int it = 0; it < 1000000; ++it)
        foo(s);
    std::cout << "foo took " << (clock() - start) << " cycles" << std::endl;

    start = clock();
    for (int it = 0; it < 1000000; ++it)
        bar(s);
    std::cout << "bar took " << (clock() - start) << " cycles" << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

aux.cpp:

#include <string>
std::string mystring;

void foo(std::string s) { mystring = s; }
void bar(const std::string& s) { mystring = s; }
Run Code Online (Sandbox Code Playgroud)

用'g ++ -O3 test.cpp aux.cpp'编译并获得打印输出:

foo took 93044 cycles
bar took 10245 cycles
Run Code Online (Sandbox Code Playgroud)

通过引用传递更快一个数量级.

  • 此测试具有误导性,因为您正在比较制作两个副本与一个副本之间的差异(显然两个较慢).关于传递值的真正主张是,如果我们要复制参数,我们应该传递值*然后将参数移动到目标*中.所以`foo`的主体看起来应该像`mystring = :: std :: move(s)`.我想你会发现在这种情况下结果大不相同. (3认同)
  • 所以我尝试了肯的想法。const ref:~12000 个周期。两份:16000 次循环。复制 + 移动:~12000 次循环。然后我尝试使用长字符串并得到: const ref: ~12000 个周期。两份:80000 次循环。复制 + 移动:~80000 次循环。const ref 似乎始终更高效 (2认同)

Jam*_*lis 20

我是否应该总是通过const引用将std :: string传递给函数,如果在该函数内完成的所有内容都是复制该字符串?

不.如果您要复制函数内部的字符串,则应该按值传递.这允许编译器执行多个优化.更多信息,请阅读Dave Abraham的"想要速度?通过价值传递".

传递值和传递参考之间有什么区别(性能或其他)?据我所知,一个使用operator =和另一个复制构造函数.是这样的吗?

不,这根本不是这样.引用不是对象; 它是对象的引用.传递值时,会传递要传递的对象的副本.当您通过引用传递时,将对现有对象进行引用,并且没有副本. 一本好的C++入门书将详细解释这些基本概念.如果要使用C++开发软件,了解基础知识至关重要.