【问题标题】:C++ functions taking values, where they should be taking referencesC++ 函数取值,它们应该取值的地方
【发布时间】:2011-01-20 09:15:06
【问题描述】:

我刚学c++,从c开始,书中看到的一些函数调用让我很困惑:

char a;
cin.get(a);

在 C 中,这不可能工作,如果你这样做,将无法获得输出,因为你是按值传递,而不是通过引用,为什么这在 c++ 中工作?引用和取消引用是隐式的(编译器知道 cin.get 需要一个指针,所以它被引用了)?

【问题讨论】:

  • C 没有引用,只有值。 C++ 有另一个实例的实际引用、别名。
  • 那么一元 & 运算符的名称是什么?我以为是引用运算符。
  • & 在 C 中表示“地址”。在 C++ 中,& 表示“地址”(如果在变量前面使用)或“引用”(如果在参数类型之后使用)。

标签: c++ pointers reference pass-by-reference pass-by-value


【解决方案1】:

这就是为什么一些 C++ 程序员不喜欢这样使用引用的原因。
它看起来像一个函数争论 - 你从语法中不知道 'a' 是否被修改。

更喜欢传递 const 引用(当你有一个大对象并且副本会很昂贵时)并返回引用或最好的传递指针。

【讨论】:

  • -1 因为按参数返回是完全有效且良好的风格(经验丰富的 C++ 程序员,包括标准委员会,都会这样做)。
  • @Martin - 当一个方法需要返回多个值时,这不太好用。
  • 返回引用可能会带来麻烦,因为调用者无法控制返回引用所引用的对象的生命周期。特别是,如果您返回对堆栈对象的引用,您的调用者将会非常痛苦:)
  • 我之前看到过这样的说法:'有经验的 c++ 程序员不喜欢使用引用'......仍然想知道那些'有经验的 c++ 程序员'是谁。我觉得这种说法有点主观,除非你能提供这方面的文献。我在知名 C++ 大师读过的任何书中都没有看到这种说法。
【解决方案2】:

C++

这适用于 C++,因为 get() 的函数签名可能是这样的:

void get(char& a); // pass-by-reference

char 之后的 & 符号表示编译器,而不是当您传入 char 值时,它应该将 reference 传递给 char 而不是复制。

这实质上意味着在get() 中所做的任何更改都将反映在方法外部a 的值中。

如果get() 的函数签名是这样的:

void get(char a); // pass-by-value

那么a 将通过 传递,这意味着在将a 作为参数传递给方法之前,会创建一个副本。对a 的任何更改都只会是方法本地的,并且会在方法返回时丢失。

C

这在 C 中不起作用的原因是因为 C 只有 pass-by-value。在 C 中模拟 pass-by-reference 行为的唯一方法是按值传递其指针,然后在修改方法:

void get(char* a)
{
    *a = 'g';
}

int main(int argc, char* argv[])
{
    char a = 'f';
    get(&a);
    printf("%c\n", a);

    return 0;
}

运行这个程序会输出:

g

【讨论】:

    【解决方案3】:

    C++ 允许通过引用传递(注意&,表示使用了引用):

    void foo(char& bar) {
        bar = 42;
    }
    
    int main() {
        char a;
        foo(a);
        // a == 42 here
    }
    

    【讨论】:

      【解决方案4】:

      引用类型就是这样工作的(通过引用传递,而不是通过值传递)。它类似于在 C 中传递指针(按指针传递),但具有更好的语法和更高的安全性(编译时检查)。实现在内部通过指针传递。

      【讨论】:

      • +1。在 C 中,它与 cin.get(&a) 一起使用,就像在 scanf("%c", &a) 中一样,它是通过指针传递的。
      • 如果我没记错的话,并不要求将引用实现为指针,尽管它们通常是。
      • 不是必需的,但 AFAIK 的所有实现都是这样做的(无论如何,对于函数调用)。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-08-04
      • 2021-03-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-28
      相关资源
      最近更新 更多