代码之家  ›  专栏  ›  技术社区  ›  Fire Lancer

小型简单结构是否应通过常量引用传递?

  •  18
  • Fire Lancer  · 技术社区  · 14 年前

    我一直被教导,非原始类型应该通过常量引用传递,而不是尽可能通过值传递,即:

    void foo(std::string str);//bad
    void foo(const std::string &str);//good
    

    但我今天在想,也许实际上一些简单的用户定义类型可以更好地通过值传递,例如:

    class Vector2
    {
    public:
        float x, y;
        ...constructors, operators overloads, utility methods, etc...
    };
    
    void foo(Vector2 pos);
    void foo(const Vector2 &pos);//is this really better than by value?
    void foo(float x, float y);//after all isn't by value effectively doing this?
    

    我的想法是,通过引用传递vector2,实际上比传递值要贵,因为编译器现在使用指针和取消引用来访问const vector2&pos版本?

    是这样吗?简单对象是否最好按值传递?应该在哪里画这条线?

    6 回复  |  直到 14 年前
        1
  •  8
  •   Peter G.    14 年前

    是的,简单对象应该按值传递。这条线必须根据建筑来画。如有疑问,请概述。

        2
  •  1
  •   Matt Davis    14 年前

    传递常量引用可避免构造新对象。如果您的构造函数是非常重要的,例如,它分配内存,那么您将 许多的 传递常量引用比传递值更好。

    在C世界中,您通过选择是创建类还是结构来做出这个决定。类使用引用语义,而结构使用值语义。我读过的每一篇文章都说,一般来说,你应该选择把每件事情都变成一个类,除非它非常小,即16字节的顺序。如果您正在寻找何时通过C++中的值与const引用的截断,那么16字节似乎是一个合理的阈值。

        3
  •  1
  •   T.E.D.    14 年前

    就像策略一样,我通过常量引用传递任何不是基本C数据类型的对象。这样更容易记住。

        4
  •  1
  •   rlduffy    14 年前

    一个古老的,但清晰的,通过参数的输入-输出分析可以在 http://www.ddj.com/184403855 . 当然,C++0X消除了许多与移动语义相关的问题,但是本文提供了很多理由来说明为什么移动语义是可取的。

        5
  •  1
  •   supercat    14 年前

    我没有提到的一个因素是例程将如何处理传入的值。除非该例程以内联方式展开,否则通过引用传递的操作数据将需要比通过值传递的操作数据更多的代码。如果传入结构的字段平均访问次数少于一次,那么与复制结构的开销相比,这个额外开销将很小。如果它们平均每个都要被访问多次,那么将它们放在堆栈中可能会更好。如果接口已经被设置为大量访问的结构的旁路引用,那么被调用的例程复制所有感兴趣的部分可能是有意义的。另一方面,如果被调用的例程无论如何都要复制结构的大部分或全部,那么它也可以通过值传递。

        6
  •  0
  •   a1ex07    14 年前

    我的想法是,通过引用传递vector2,实际上比传递值要贵,因为编译器现在使用指针和取消引用来访问const vector2&pos版本。

    如果你通过一个物体 size_of(object) < size_of(pointer_to_object) . 例如, char const& 可能比 char