Sec*_*ret 36 c# pointers memory-management reference ref
我正在使用ref并且不明白"它是像C/C++中的指针还是像C++中的引用一样?"
为什么我问你这么弱的问题?因为,当我正在阅读C#/.NET书籍,msdn或与C#开发人员交谈时,我会因以下原因而感到困惑:
ref在函数的参数中使用,e.g. ...(ref Type someObject)对他们没有好处,他们建议...(Type someObject),我真的不明白这个建议.我听到的原因:更好地处理对象的副本,然后将其用作返回值,而不是通过引用等来破坏内存...通常我会听到有关数据库连接对象的这种解释.就像我简单的C/C++体验一样,我真的不明白为什么使用引用是C#中的坏东西?我控制对象的生命及其内存分配/重新分配等...我在书籍和论坛中只读了建议it's bad, because you can corrupt your connection and cause a memory leak by a reference lose,所以我控制对象的生命,我可以手动控制我真正想要的东西,那为什么它不好?ref一个指针(*)或像C++中的引用&吗?我记得C/C++中的指针总是分配一个大小为void*4字节的空间(有效大小取决于体系结构),其中主机是结构或变量的地址.在C++中,通过传递引用&,没有来自堆/堆栈的新分配,并且您在内存空间中使用已定义的对象,并且外部没有像在纯C中那样的指针的子分配内存.那么refC#中的内容是什么?.NET VM是否像普通C/C++中的指针一样处理它,它为指针GC分配临时空间,还是像C++中的引用那样工作?是否ref只能正确使用托管类型或者类似于值类型bool, int,更好地切换unsafe代码并以非托管样式传递指针?Bil*_*eal 37
在C#中,当您看到引用引用类型的某些内容(即,使用class而不是声明的类型struct)时,您基本上总是通过指针处理该对象.在C++中,默认情况下一切都是值类型,而在C#中,默认情况下一切都是引用类型.
当你在C#参数列表中说"ref"时,你真正说的更像是"指向指针的指针".在方法中,您要说的是,在调用方法的代码中,您不想替换对象的内容,而是替换对象本身的引用.
除非那是你的意图,否则你应该直接传递引用类型; 在C#中,传递引用类型很便宜(类似于在C++中传递引用).
了解/理解C#中值类型和引用类型之间的区别.它们是该语言中的一个主要概念,如果您尝试在C#land中使用C++对象模型,那么事情将会非常混乱.
以下基本上是语义上等效的程序:
#include <iostream>
class AClass
{
    int anInteger;
public:
    AClass(int integer)
        : anInteger(integer)
    {  }
    int GetInteger() const
    {
        return anInteger;
    }
    void SetInteger(int toSet)
    {
        anInteger = toSet;
    }
};
struct StaticFunctions
{
    // C# doesn't have free functions, so I'll do similar in C++
    // Note that in real code you'd use a free function for this.
    static void FunctionTakingAReference(AClass *item)
    {
        item->SetInteger(4);
    }
    static void FunctionTakingAReferenceToAReference(AClass **item)
    {
        *item = new AClass(1729);
    }
};
int main()
{
    AClass* instanceOne = new AClass(6);
    StaticFunctions::FunctionTakingAReference(instanceOne);
    std::cout << instanceOne->GetInteger() << "\n";
    AClass* instanceTwo;
    StaticFunctions::FunctionTakingAReferenceToAReference(&instanceTwo);
    // Note that operator& behaves similar to the C# keyword "ref" at the call site.
    std::cout << instanceTwo->GetInteger() << "\n";
    // (Of course in real C++ you're using std::shared_ptr and std::unique_ptr instead,
    //  right? :) )
    delete instanceOne;
    delete instanceTwo;
}
对于C#:
using System;
internal class AClass
{
    public AClass(int integer)
        : Integer(integer)
    {  }
    int Integer { get; set; }
}
internal static class StaticFunctions
{
    public static void FunctionTakingAReference(AClass item)
    {
        item.Integer = 4;
    }
    public static void FunctionTakingAReferenceToAReference(ref AClass item)
    {
        item = new AClass(1729);
    }
}
public static class Program
{
    public static void main()
    {
        AClass instanceOne = new AClass(6);
        StaticFunctions.FunctionTakingAReference(instanceOne);
        Console.WriteLine(instanceOne.Integer);
        AClass instanceTwo  = new AClass(1234); // C# forces me to assign this before
                                                // it can be passed. Use "out" instead of
                                                // "ref" and that requirement goes away.
        StaticFunctions.FunctionTakingAReferenceToAReference(ref instanceTwo);
        Console.WriteLine(instanceTwo.Integer);
    }
}
fre*_*low 22
refC#中的A 等同于C++引用:
一些C++代码:
void foo(int& x)
{
    x = 42;
}
// ...
int answer = 0;
foo(answer);
等价的C#代码:
void foo(ref int x)
{
    x = 42;
}
// ...
int answer = 0;
foo(ref answer);