简体   繁体   English

在调用函数时,ptr **和ptr *之间是否存在差异,或者在C ++中是否存在差异?

[英]Is there a difference, or preferred between ptr** and ptr*& in C++ when calling functions?

Is there a difference or preferred way of altering a pointer in a function? 是否有改变函数中指针的差异或首选方法? Take this snippet for example 以此片段为例

    void change(int** ptr) {
        **ptr = 50;
        *ptr = nullptr;
    }

    void change(int*& ptr) {
        *ptr = 50;
        ptr = nullptr;
    }

    int main()
    {
        int a = 5;

        int* ptr = &a;
        int** ptr2 = &ptr;

        std::cout << "value: " << a << std::endl;
        std::cout << "value: " << ptr << std::endl;
        std::cout << "value: " << ptr2 << std::endl;

        change(ptr2);
        //change(ptr);

        std::cout << "value: " << a << std::endl;
        std::cout << "value: " << ptr << std::endl;
        std::cout << "value: " << ptr2 << std::endl;


        system("pause");

    }

It seems like both of the change functions can achieve what I'm asking, but I'm not sure on the difference, other than the reference function doesn't create a copy of the pointer? 似乎两个更改函数都可以实现我所要求的,但我不确定区别,除了引用函数不创建指针的副本?

You can have a null pointer, but not a null reference. 您可以使用空指针,但不能使用空引用。

You can supply the first with nullptr , and it will compile 1 , because there is an implicit conversion from std::nullptr_t to int** . 您可以使用nullptr提供第一个,并且它将编译1 ,因为存在从std::nullptr_tint**的隐式转换。 If you tried to supply the second with nullptr , it will fail. 如果您尝试使用nullptr提供第二个,它将失败。 The best match would be the conversion std::nullptr_t to int* , but you can't bind a mutable reference to a temporary. 最好的匹配是将std::nullptr_t转换为int* ,但是您不能将可变引用绑定到临时。

I go over various situations for different ways of parameter passing in this answer , which also includes object ownership considerations (with std::unique_ptr ) 在这个答案中讨论了不同的参数传递方式的各种情况,其中还包括对象所有权注意事项(使用std::unique_ptr

1. The behaviour will be undefined, because you dereference it. 1.行为将是未定义的,因为您取消引用它。

Is there a difference ... between ptr** and ptr*& ... ptr **和ptr之间是否有区别*&...

Yes. 是。 The former is a pointer, to an object of type ptr* , while the latter is a reference to an object of type ptr* . 前者是指向ptr*类型的对象的指针,而后者是对ptr*类型的对象的引用。

or preferred ... 或者首选......

 void change(int** ptr) { **ptr = 50; *ptr = nullptr; } void change(int*& ptr) { *ptr = 50; ptr = nullptr; } 

Advantages of a reference 参考的优点

You'll find that the reference is implicitly indirected, which makes the syntax simpler and that usually helps readability. 您会发现该引用是隐式间接的,这使得语法更简单,并且通常有助于提高可读性。 This is particularly important in case of reference / pointer to a pointer. 在指向指针的引用/指针的情况下,这尤其重要。 Same advantage applies to getting a reference: You don't need to use the address-of operator. 同样的优势适用于获取引用:您不需要使用address-of运算符。

Another advantage is that a reference cannot be reassigned to refer to another object. 另一个优点是不能重新分配引用以引用另一个对象。 This makes it simpler to read programs that use references, since you don't need to figure out whether a reference is reassigned within a long algorithm; 这使得读取使用引用的程序变得更加简单,因为您不需要弄清楚是否在长算法中重新分配了引用; You know that it isn't. 你知道事实并非如此。

Another advantage is that a reference cannot be null. 另一个优点是引用不能为空。 Therefore you don't need to check for such eventuality within the function. 因此,您无需在函数中检查此类可能性。 If you pass null to the first example function, the behaviour would be undefined, which is a very bad thing. 如果将null传递给第一个示例函数,则行为将是未定义的,这是一件非常糟糕的事情。

Disadvantages of a reference 参考的缺点

You'll find that the reference is implicitly indirected. 您会发现该引用是隐式间接的。 This can be confusing to people who are familiar with only value types (C programmers). 对于只熟悉价值类型(C程序员)的人来说,这可能会让人感到困惑。

Another disadvantage is that a reference cannot be reassigned to refer to another object. 另一个缺点是不能重新分配引用以引用另一个对象。 This appears to not be a problem for your function since you don't need to refer to more than one object, but in general, there are situations where it would be useful. 这对您的函数来说似乎不是问题,因为您不需要引用多个对象,但通常情况下,它会有用。

Another disadvantage is that a reference cannot be null. 另一个缺点是引用不能为空。 This appears to not be a problem for your function which is presumably never intended to handle such case. 对于您的功能而言,这似乎不是问题,而这可能无法用于处理此类情况。 But in general, there are situations where you want to represent a referential relation to non-existing object. 但总的来说,在某些情况下,您希望表示与不存在的对象的引用关系。


Preferences are personal, but in my opinion, the advantages of the reference outweigh the disadvantages, except when you need one of the features that are not possible (nullability, re-assignment) 偏好是个人的,但在我看来,参考的优点超过了缺点,除非你需要一个不可能的功能(可空性,重新分配)

It's largely a matter of personal taste. 这主要取决于个人品味。

That said, when calling void change(int** ptr) , because you'd tend to pass the address of something using & , it is clearer at the calling site that the "something" could be modified by the function. 这就是说,当调用void change(int** ptr)因为你往往通不过的东西使用的地址& ,它是在调用现场的“东西” 可以通过函数修改清晰。 If you use the int*& ptr overload, it's not as clear as the calling syntax is identical for pass-by-value and pass-by-reference. 如果你使用int*& ptr重载,它就不像调用语法对于pass-by-value和pass-by-reference一样清晰。

Aside from the above, I tend to use pointers as function parameters if nullptr is allowed, and references if not. 除了上面的内容之外,如果允许nullptr ,我倾向于使用指针作为函数参数,如果不允许则使用引用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM