Afr*_*ief 60

当你传递一个大的结构/类时,差异更加突出.

struct MyData {
    int a,b,c,d,e,f,g,h;
    long array[1234];
};
void DoWork(MyData md);
void DoWork(const MyData& md);
Run Code Online (Sandbox Code Playgroud)

当您使用'normal'参数时,您可以按值传递参数,从而创建您传递的参数的副本.如果您使用const引用,则通过引用传递它,并且不会复制原始数据.

在这两种情况下,都无法从函数内部修改原始数据.

编辑:
在某些情况下,原始数据可能会被查尔斯贝利答案中指出修改.

  • 通过 ref 当然不需要 `const`.. 只是通过使用 `const`,编译器将帮助您避免修改原始数据.. 但这可以被故意绕过,正如 Charles Bailey 所指出的.. (4认同)
  • 通过 ref 传递是否需要 `const`?我的意思是,您的答案不适用于我们将“正常”参数与引用参数进行比较的情况吗? (3认同)

CB *_*ley 58

重要的区别在于,通过const引用传递时,不会创建新对象.在函数体中,参数实际上是传入的对象的别名.

因为引用是const引用,所以函数体不能直接改变该对象的值.它具有与传递值类似的属性,其中函数体也不能更改传入的对象的值,在这种情况下,因为参数是副本.

有重要的区别.如果参数是const引用,但实际上没有传递它的对象,const那么在函数调用本身期间可能会更改对象的值.

例如

int a;

void DoWork(const int &n)
{
    a = n * 2;  // If n was a reference to a, n will have been doubled 

    f();  // Might change the value of whatever n refers to 
}

int main()
{
    DoWork(a);
}
Run Code Online (Sandbox Code Playgroud)

此外,如果传入的对象实际上不是,const那么函数可以(即使建议不通)使用强制转换来更改其值.

例如

void DoWork(const int &n)
{
    const_cast<int&>(n) = 22;
}
Run Code Online (Sandbox Code Playgroud)

如果实际传入的对象,这将导致未定义的行为const.

当参数通过const引用传递时,额外的成本包括解除引用,更糟的对象局部性,更少的编译优化机会.

当参数按值传递时,需要额外的成本来创建参数副本.通常,当对象类型很大时,这只是一个问题.

  • 您能否解释一下当您在答案中提到_更糟糕的对象局部性_时会受到什么惩罚? (3认同)

小智 14

您可以在函数中传递三种方法

  1. 通过价值

    void f(int n){
        n = n + 10;
    }
    
    int main(){
        int x = 3;
        f(x);
        cout << x << endl;
    }
    
    Run Code Online (Sandbox Code Playgroud)

    输出:3.缺点:当参数x传递f函数时,编译器在x的内存中创建一个副本.所以浪费了记忆.

  2. 通过引用传递

    void f(int& n){
        n = n + 10;
    }
    
    int main(){
        int x = 3;
        f(x);
        cout << x << endl;
    }
    
    Run Code Online (Sandbox Code Playgroud)

    输出:13.它消除了传递值的缺点,但如果程序员不想更改值,则使用常量引用

  3. 不断参考

    void f(const int& n){
        n = n + 10; // Error: assignment of read-only reference  ‘n’
    }
    
    int main(){
        int x = 3;
        f(x);
        cout << x << endl;
    }
    
    Run Code Online (Sandbox Code Playgroud)

    输出:抛出错误n = n + 10因为当我们传递const引用参数参数然后它是只读参数时,你不能改变n的值.

  • 您的意思是在调用 f() 之后在 main() 中包含 print 语句吗?因为使用 f() 内部的 print 语句,我认为第一个示例的输出是错误的:它应该是 13,不是吗? (2认同)

Avi*_*Avi 6

 void DoWork(int n);
Run Code Online (Sandbox Code Playgroud)

n是实际参数值的副本,更改n函数内的值是合法的.同

void DoWork(const int &n);
Run Code Online (Sandbox Code Playgroud)

n 是对实际参数的引用,更改其值是不合法的.


Aoi*_*asu 5

因为你们都没有提到 const 关键字......

常量关键字修改类型声明的类型或函数参数的类型,从而防止改变值。(来源:女士)

换句话说:通过引用传递参数会将其暴露给被调用者修改。使用const关键字可防止修改。