之前也一直纳闷这个问题,为什么有两个差不多的东西,以及函数传参数的时候为什么一般都传引用,很少有用指针的。之前是按照这篇理解的----函数何时值传递,何时指针,何时引用传递总结

文章写的有点长,摘点重要的

  1. 指针传递需要开内存,如果忘记释放的话,可能导致内存泄露。浪费大量内存。所以引用传递更好一些。

  2. 在定义函数时,还可以让它以“引用传递”方式而不是以“值传递”方式返回:int &myFuntion();

  3. 除了可以改变有关变量的值,“引用传递”方式的另一个好处是它的开销相对要小一些:因为不需要在函数里创建临时变量来容纳那些值,程序的内存占用量当然会小一些。

  4. 如果想获得“引用传递”方式带来的性能改善,但不想改变某个变量的值,可以把相应的输入参数定义为一个常量:void myFunc(const int &myNum);通过这样定义的函数,可以把具体的参数直接传递给它:myFunc(7);

  5. 最重要的一点,也是上文中花笔墨最多的。简述一下:指针传递的本质也是跟值传递一样,只不过不是值的拷贝而是地址的拷贝。这会引发一个问题,如

     char *str = "this is a test";
       int change(char* name)
       {
           name="alter";
           return 1;
       }
        change(str);
    

    这样传递参数的时候,str和name虽然都是存的“this is a test”字符串的首地址,但&str和&name是不一样的,是两个地址。这样再对name="alter"的时候,name存的地址变化了,但是str没变。这里应该传二级指针。

    如果我们使用引用的话就没事。是一样的地址。


C++原作者回答

Why does C++ have both pointers and references?

[Why does C++ have both pointers and references?]

C++ inherited pointers from C, so I couldn't remove them without causing serious compatibility problems. References are useful for several things, but the direct reason I introduced them in C++ was to support operator overloading. For example:

    void f1(const complex* x, const complex* y) // without references
    {
        complex z = *x+*y;  // ugly
        // ...
    }

    void f2(const complex& x, const complex& y) // with references
    {
        complex z = x+y;    // better
        // ...
    }   

More generally, if you want to have both the functionality of pointers and the functionality of references, you need either two different types (as in C++) or two different sets of operations on a single type. For example, with a single type you need both an operation to assign to the object referred to and an operation to assign to the reference/pointer. This can be done using separate operators (as in Simula). For example:

    Ref<My_type> r :- new My_type;
    r := 7;         // assign to object
    r :- new My_type;   // assign to reference

Alternatively, you could rely on type checking (overloading).For example:

    Ref<My_type> r = new My_type;
    r = 7;          // assign to object
    r = new My_type;    // assign to reference

Should I use call-by-value or call-by-reference?

That depends on what you are trying to achieve:

  • If you want to change the object passed, call by reference or use a pointer; e.g. void f(X&); or void f(X*);
  • If you don't want to change the object passed and it is big, call by const reference; e.g. void f(const X&);
  • Otherwise, call by value; e.g. void f(X);

What do I mean by "big"?

Anything larger than a couple of words.(因为指针传递需要开内存)

Why would I want to change an argument? Well, often we have to, but often we have an alternative: produce a new value. Consider:

    void incr1(int& x); // increment
    int incr2(int x);   // increment

    int v = 2;
    incr1(v);   // v becomes 3
    v = incr2(v);   // v becomes 4

I think that for a reader, incr2() is easier to understand. That is, incr1() is more likely to lead to mistakes and errors. So, I'd prefer the style that returns a new value over the one that modifies a value as long as the creation and copy of a new value isn't expensive.

I do want to change the argument, should I use a pointer or should I use a reference? I don't know a strong logical reason. If passing ``not an object'' (e.g. a null pointer) is acceptable, using a pointer makes sense. My personal style is to use a pointer when I want to modify an object because in some contexts that makes it easier to spot that a modification is possible.

Note also that a call of a member function is essentially a call-by-reference on the object, so we often use member functions when we want to modify the value/state of an object.


一沙一世界,一花一天堂。君掌盛无边,刹那成永恒。