代码之家  ›  专栏  ›  技术社区  ›  DaveUK

C++通过值与引用传递一个const结构参数有什么意义?

  •  2
  • DaveUK  · 技术社区  · 6 年前

    假设一个基本C++类:

    class MyClass
    {
    public:
        struct SomeData
        {
            std::wstring name;
            std::vector<int> someValues;
        };
    
        void DoSomething(const SomeData data);
    }
    

    data 将作为 const DoSomething 数据 & 用指定 常数

    void DoSomething(const SomeData& data);
    

    这对我来说似乎更有效率。如果我们忽略 & ,那不是吗 数据 通过值传递给 剂量测定 ? 我不知道为什么通过考试会更好 常数

    4 回复  |  直到 6 年前
        1
  •  4
  •   PraAnj OhadR    6 年前

    传递值/引用和常量正确性是两个不同的概念。但是一起使用。

    传递值

     void DoSomething (SomeData data);
    

    通过引用传递

    void DoSomething (SomeData& data);
    

    如果您知道复制结构可能会导致性能损失,请始终使用引用传递。这个函数在某些情况下可以(如果它在一个类中)保持指向它的指针,并指向一个外部对象。保持指向外来对象的指针意味着您应该知道它的生命周期以及这个外来对象何时会越界。更重要的是,对外来对象的更改会出现在指针上。

    const正确性

    void DoSomething (const SomeData data);  // const for local copy
    void DoSomething (const SomeData& data); //  const for callers object
    

    添加 const 按值或引用传递意味着此函数不会更改它。但是没有或者没有 & 决定要添加修改安全性的对象。 是一个非常有用的工具,C++在文档API方面,提供编译时安全性,允许更多编译器优化。

    Read

        2
  •  2
  •   Christian Hackl    6 年前

    最大的问题是 void DoSomething(const SomeData data) 它将接口和实现结合起来。从来电者的角度来看 const 不会更改任何内容;函数仍会接收副本,并且不会修改原始对象。实现本身的函数内部拷贝所做或不做的事情不应困扰调用者,因此不应在接口中表达。

    这个 常数 如果不更改副本,则会使实现更加正确,但将实现细节泄漏到接口中是一个很高的代价。我建议不要使用 .

    与以往一样,在这里不应高估绩效的收益或损失。更多的是关于语义和约定。

        3
  •  0
  •   Some programmer dude    6 年前

    路过 const 值对于调用者来说主要是信息性的,它表示意图。这对于使代码易于阅读、理解和维护非常重要。

    如果编译器知道函数没有修改它的参数,那么它也可以添加一些额外的优化。例如,它可能会导致编译器根本不执行复制。

        4
  •  0
  •   John Zwinck    6 年前

    这是:

    void DoSomething(const SomeData data);
    

    有点不寻常,因为虽然它不会为调用者(可以传递常量或非常量值)更改任何内容,但它限制了函数可以在内部执行的操作。这没有多大的价值,也不是一般的做法。

    如果值的复制成本很高,包括如果值大于目标平台上大约两个指针,则按引用传递(const或not)会更有效。换句话说,如果 SomeData 如果结构包含两个整数,按值传递可能会更有效。但如果它含有 std::map 或者一些较大的数据,最好通过引用传递。