代码之家  ›  专栏  ›  技术社区  ›  Peter Oehlert

C是作为一个C++ INT*FO实现的吗?

  •  3
  • Peter Oehlert  · 技术社区  · 15 年前

    我昨天和一个同事谈过这个问题,这让我想到了.NET的参考传递。

    // C#
    class Foo {}
    
    static void Test(ref Foo foo) { ... };
    static void Main()
    { 
        Foo f;
        Test(ref foo);
    }
    

    必须用双间接寻址实现,因为我们正在更改指针的值。因为所有引用类型都是引用(指针)

    // C#
    static void Test(Foo foo) { ... }
    static void Test(ref Foo foo) { ... };
    

    相当于

    // C++
    void Test(Foo *foo);
    void Test(Foo **foo);
    

    但如果这是 价值 类型,我们实际上不需要双重间接。所以我很好奇

    // C#
    static void Test(ref int bar) { ... }
    

    变成

    // C++
    void Test(int *bar);
    // or
    void Test(int **bar);
    

    1/29/10更新: 读了所有的答案,我意识到我不太清楚我想要什么,我误导了C++。我主要感兴趣的是它是如何在CLR中实现的,以及JIT将如何为它生成程序集。感谢所有的答案,我发现他们都是正确的,从一个角度来看,但我选择了一个最接近我的问题。 思想 我曾经问过。

    7 回复  |  直到 15 年前
        1
  •  5
  •   Eric Lippert    15 年前

    在C中,当您有一个方法时

    void M(ref int f) { }
    

    你称之为

    int x = 123;
    M(ref int x):
    

    这是怎么工作的?

    逻辑上 ,这意味着“X和F表示相同的存储位置”。

    我们实际实施的方式 在CLR中 is f的类型为“可包含整数的变量的托管引用”。我们将局部变量x的托管地址传递给m。

    C++中的模拟将是一种方法,它使用ANP;INT——对包含INT的变量的引用。

    明白了吗?

        2
  •  6
  •   jason    15 年前

    正确的思考方式 ref 是存储位置的别名。因此,当你说

    int x;
    Foo(ref x);
    

    Foo 被宣布为

    void Foo(ref int y)
    

    你得想想 x y 作为上述方法调用中相同位置的别名。

    所以, void Foo(ref int y) 在C中,类似于 void Foo(int &y) 在C++中。

        3
  •  5
  •   dtb    15 年前

    引用不是指针。


    Foo foo = new Foo();
    

    这声明了一个“内存单元”,它保存对foo实例的引用。然后它初始化的新实例 Foo 并将引用存储在内存单元中。

    Bar(Foo x) { x = new Foo(); }
    

    此声明方法的 参数,它本质上是一个局部变量(如foo),当使用参数调用该方法时,会自动分配该变量。

    方法中的语句创建的新实例 并将对实例的引用存储在内存单元中 x .存储单元 foo 保持不变。

    Bar(foo);
    

    这个调用 Bar 通过复制存储在内存单元中的值 记忆细胞 X —— 按值调用 .

    如果你写的话也会发生同样的事情 int 而不是 ,但存储在内存单元中的值不是引用而是实际值。


    Qux(ref Foo y) { y = new Foo(); }
    

    这声明了一个方法 Foo& 参数,它本质上是一个局部变量,包含对类型对象的引用的内存单元的地址。 .

    Qux(ref x);
    

    这个调用 Qux 通过设置 y 到存储单元的地址 X —— 参考呼叫 .

    陈述 奎克斯 创建的新实例 并将对对象的引用存储在位于地址的内存单元中 Y (地址是 )所以 已将引用分配给新实例和更改。

    是一个 int ,除了存储在通过引用传递的内存单元中的值不是对对象的引用,而是对实际值的引用。

        4
  •  0
  •   Filip Ekberg    15 年前

    引用不是*您将它与指针混淆。所以这意味着它将被传递为:

    void Test(Foo &bar);
    
        5
  •  0
  •   ChrisV    15 年前

    我很确定像int这样的值类型只使用一个间接级别。

        6
  •  0
  •   isekaijin    15 年前
    1. MyClass ---GT; MyClass* (或者,实际上, shared_ptr<MyClass> )
    2. ref ---GT; &

    C:

    void doSomething(int myInt);
    void doSomethingElse(ref int myIntRef);
    void doSomething(Foo foo);
    void doSomethingElse(ref Foo fooRef);
    

    C++:

    void doSomething(int myInt);
    void doSomethingElse(int& myInt);
    void doSomething(Foo* fooPtr);
    void doSomething(Foo*& fooPtrRef);
    
        7
  •  0
  •   liori    15 年前

    您可能想检查它是如何在C++/CLI中实现的。我在一本书中找到了很好的解释: Expert C++/CLI: NET for Visual C++ programmers ,第83页。

    Foo^ 定义为“指向foo的托管指针”,相当于 UnmanagedFoo* .

    int% Foo^% 是“托管引用”,它们等同于 int& UnmanagedFoo*& .