如何根据 C++ 在同一内存位置重新初始化 C# 中的对象(或者它是自动完成的)?
How to reinitialize an object in C# at the same memory location in terms of C++ (or is it done automatically)?
在 C++ 中,我使用了像
这样的结构
#include "stdafx.h"
#include "TestStaticPointer.h"
MyClass* MyClass::myStaticPointer;
int main()
{
ProgrammStart();
return 0;
}
void ProgrammStart()
{
MyClass::myStaticPointer = new MyClass();
}
void SomeProgrammPlace()
{
*MyClass::myStaticPointer = MyClass();
}
所以我只在 ProgrammStart() 中分配了一次内存,然后我使用相同的内存位置重新初始化我的静态指针(没有通过 'new' 重新分配),我只是使用构造 "= MyClass(); ”。
如何在 C# 中执行此操作? IL 是否承担了所有关于分配的工作?就 C++ 而言,'new' 是否总是表示 'new' 内存位置(内存中的不同位置)?
首先,您还没有重新初始化任何东西。您在这里所做的是 作业。您创建了一个新的 MyClass
对象,并通过调用其赋值运算符将现有 MyClass
对象的状态修改为与新对象相同。
在 C# 中分配给 struct
时会发生同样的事情:
class Program
{
static void Main(string[] args)
{
MyStruct mc = new MyStruct(10);
// Will print 10
Console.WriteLine(mc.i);
unsafe
{
MyStruct* pmc = &mc;
// Will print the address of mc
Console.WriteLine((IntPtr)pmc);
}
// Assign to mc
mc = new MyStruct(20);
// Will print 20; mc was modified
Console.WriteLine(mc.i);
unsafe
{
MyStruct* p = &mc;
// Will print the same address as above.
// mc was modified in place
// because structs have value semantics
Console.WriteLine((IntPtr)p);
}
}
}
struct MyStruct
{
public MyStruct(int i)
{
this.i = i;
}
public int i;
}
你能够在 C++ 中做你正在做的事情的原因是开发人员需要在 C++ 中管理内存(当你的工作完成时释放它)。
但是在像 Dot Net 这样的托管环境中,CLR(公共语言运行时)将为您负责内存管理(何时以及需要释放哪些内存,它做得很好。)。
与您的问题最接近的答案是为对象创建弱引用。这样您就可以在将来需要时调用这些引用。请注意,具有弱引用的对象在常规情况下不会被 *Garbage Collector 收集。当创建特定对象的过程繁重时使用弱引用,在这种情况下,为了避免从头开始创建对象,将围绕该对象创建弱引用。在回收你WR之前,你还需要检查对象是否存在并且没有被GC回收(一些角落情况,比如内存不足。)
应非常小心地使用弱引用,否则它们会产生开销而不是解决您的问题。在 Dot Net 世界里最好的建议是不要自己做内存管理,让 GC 来处理。不过,有一些最佳实践需要遵循才能使 GC 生活更轻松。
如果您想了解更多关于 Dot Net 中的内存管理,可以参考 Under the Hood of .NET Memory Management
*垃圾收集器 - 管理环境有一个称为垃圾收集器的东西,它负责内存管理、分配、在最佳时间释放内存。
在 C++ 中,我使用了像
这样的结构#include "stdafx.h"
#include "TestStaticPointer.h"
MyClass* MyClass::myStaticPointer;
int main()
{
ProgrammStart();
return 0;
}
void ProgrammStart()
{
MyClass::myStaticPointer = new MyClass();
}
void SomeProgrammPlace()
{
*MyClass::myStaticPointer = MyClass();
}
所以我只在 ProgrammStart() 中分配了一次内存,然后我使用相同的内存位置重新初始化我的静态指针(没有通过 'new' 重新分配),我只是使用构造 "= MyClass(); ”。
如何在 C# 中执行此操作? IL 是否承担了所有关于分配的工作?就 C++ 而言,'new' 是否总是表示 'new' 内存位置(内存中的不同位置)?
首先,您还没有重新初始化任何东西。您在这里所做的是 作业。您创建了一个新的 MyClass
对象,并通过调用其赋值运算符将现有 MyClass
对象的状态修改为与新对象相同。
在 C# 中分配给 struct
时会发生同样的事情:
class Program
{
static void Main(string[] args)
{
MyStruct mc = new MyStruct(10);
// Will print 10
Console.WriteLine(mc.i);
unsafe
{
MyStruct* pmc = &mc;
// Will print the address of mc
Console.WriteLine((IntPtr)pmc);
}
// Assign to mc
mc = new MyStruct(20);
// Will print 20; mc was modified
Console.WriteLine(mc.i);
unsafe
{
MyStruct* p = &mc;
// Will print the same address as above.
// mc was modified in place
// because structs have value semantics
Console.WriteLine((IntPtr)p);
}
}
}
struct MyStruct
{
public MyStruct(int i)
{
this.i = i;
}
public int i;
}
你能够在 C++ 中做你正在做的事情的原因是开发人员需要在 C++ 中管理内存(当你的工作完成时释放它)。
但是在像 Dot Net 这样的托管环境中,CLR(公共语言运行时)将为您负责内存管理(何时以及需要释放哪些内存,它做得很好。)。
与您的问题最接近的答案是为对象创建弱引用。这样您就可以在将来需要时调用这些引用。请注意,具有弱引用的对象在常规情况下不会被 *Garbage Collector 收集。当创建特定对象的过程繁重时使用弱引用,在这种情况下,为了避免从头开始创建对象,将围绕该对象创建弱引用。在回收你WR之前,你还需要检查对象是否存在并且没有被GC回收(一些角落情况,比如内存不足。)
应非常小心地使用弱引用,否则它们会产生开销而不是解决您的问题。在 Dot Net 世界里最好的建议是不要自己做内存管理,让 GC 来处理。不过,有一些最佳实践需要遵循才能使 GC 生活更轻松。
如果您想了解更多关于 Dot Net 中的内存管理,可以参考 Under the Hood of .NET Memory Management
*垃圾收集器 - 管理环境有一个称为垃圾收集器的东西,它负责内存管理、分配、在最佳时间释放内存。