按值或常量引用传递函数

Pass by value or const reference to function?

本文关键字:引用 传递函数 常量      更新时间:2023-10-16

我应该按值传递std::string还是通过引用传递给一个函数。此函数将此值存储在类的成员变量中。

当关于按值或引用传递时,我总是感到困惑。请清除我对此的困惑。

这是代码:

class DataStore {
public:
    void addFile(const string& filename, const set< std::string>& filePaths)
    {  
        if (dataStoreMap.insert(make_pair(filename, filePaths)).second)
        {
            cout << "Data Added" <<endl;
        }
        else
        {
            cout << "Data not Added" << endl;
        }
    }
private:
    // member variable
    map < string, set < string >  > dataStoreMap;
};

我应该像这样做函数声明吗:

void addFile(const string& filename, const set< std::string>& filePaths)

void addFile(const string filename, const set< std::string> filePaths)

两者都给出相同的结果。如果内存分配或性能有任何问题。

以上来自cpp类的函数调用。

DataStore ds;
set<string> setFileDirectory{ "1", "2", "3", "4", "6", "5" };
ds.addFile("file.txt", setFileDirectory);
setFileDirectory.erase(setFileDirectory.begin(), setFileDirectory.end());
setFileDirectory.insert({ "1", "2", "3", "4", "5", "6" });
ds.addFile("demo.txt", setFileDirectory);

任何详细的解释将不胜感激。

谢谢

当你有一个输入参数时,即函数观察到但修改的东西,考虑通过 const 引用const & ) 传递它,以避免无用的深拷贝(可能需要动态内存分配等)

void addFile(const std::string& filename, 
             const std::set<std::string>& filePaths)

附言
当然,如果您要传递复制成本较低的参数,例如int s,则可以按值传递:)

第一个具有"更好"的性能,因为第二个在传递之前会复制string。 由于您没有修改string,因此在调用函数中传递对实际字符串的引用而不是复制没有缺点,并且复制引用比复制string占用更少的内存。 也就是说,如果您从未在 string 变量上丢弃 const 说明符,编译器最终可能会等效地处理它们。 这种差异在大参数上更有用,例如,如果您的filepaths变量有几千个元素,则通过引用而不是按值传递它可能会有非常明显的差异。

相关:C++按值传递还是按常量引用传递更好?

如果您的容器集很大,并且将字符串传递给函数相对较小,我可以按如下方式使用:

void addFile(const string filename, const set< std::string> & filePaths)

首先,你永远不应该通过传递参数const因为它几乎没有任何理由。按值传递已经确保您在复制变量时无法在调用站点更改变量。

现在,问题仍然是关于按值或引用传递参数。答案比预期的要复杂得多。在Stack Overflow上有很多关于这个问题的好答案。

简而言之,当将潜在的大型对象(如std::vectorstd::string)传递给函数时,请使用以下惯用准则:

  • 当传递观察(只读)时,通过引用传递const
  • 当传递要保留副本的参数(所谓的 sink 参数)时,还要通过引用传递 const 。如果传递的对象是可移动的,您还可以添加一个重载,通过右值引用T&&)对参数进行优化。

相关信息:

  • 引用传递与按值传递有什么区别?
  • C++按值传递还是按常量引用传递更好?
  • 戴夫·亚伯拉罕斯 - 想要速度吗?按值传递
  • 什么是移动语义?
  • 为什么在 Herb Sutter 的 CppCon 2014 演讲(返璞归真:现代C++风格)中不推荐值二传手成员函数?