C++ 这些情况你应该使用按值传递(附带详细解释)—————C++2.0 知识点补充

C++2.0 知识点补充

文章目录

1 某些情况下考虑按值传递

需要按值传递的条件:对于可复制的、在移动成本低廉的并且一定会被复制的形参,按值传递可能会和按引用传递的具备相近的效率,并且可能生成更少量的目标代码。

条件解读和示例代码如下:

  • 按值传递的好处:
    • 1,只需要考虑按值传递 (相对于重载版本只要撰写单个函数;相对于万能引用版本可以避免万能引用带来的一系列问题)【效率可能没有剩余两者高】;
    • 2,仅针对可复制的形参,才考虑按值传递(如果形参是只移动类型,那么重载版本就只需要一个接受右值的重载版本,失去了按值传递的好处);
  • 3,按值传递仅在移动成本低廉的情况下,才值得考虑(因为按值传递,相对于重载和万能引用版本会多一次额外的移动操作,如果移动操作成本高,那么移动就和复制没有区别了);
  • 4,应该只针对移动会被复制的形参菜考虑按值传递。
    • 因为对于构造来实施形参复制的函数,使用按值传递,无论传入的是左值还是右值,都会招致一次额外移动所带来的成本;
    • 对于采用赋值来实施赋形参复制的,可能会导致额外的内存分配和回收的成本(例如,动态分配中存值的一部分形参类型,例如std::stringstd::vector
//版本1:左右值重载
class Widget{
public:
    void addName(const std::string& newName){
        names.push_back(newName);
    }
    void addName(std::string&& newName){
        names.push_back(newName);
    }
private:
    std::vector<std::string> names;
};
//版本2:万能引用
class Wiget{
public:
    template<class T>
    void addName(T&& newName){
        names.push_back(std::forward<T>(newName));
    }
private:
    std::vector<std::string> names;	
};
//版本3:按值传递
class Widget{
public:
    void addName(std::string newName){
        names.push_back(std::move(newName));
    }
private:
    std::vector<std::string> names;   
};

结论就是总是采用重载或者万能引用,而非按值传递,除非确定按值传递能够为所需的形参类型生成可接受效率的代码。

上一篇:软工总结 —— 最后的最后


下一篇:JavaScript Es5继承以及Es6继承