Ale*_*lex 13 c# c++ java memory memory-management
无论使用C++或C#还是Java,我的理解始终是当我们使用new关键字创建对象时,它会在堆上分配内存.我认为new只需要引用类型(类),并且原始类型(int,bool,float等)永远不会使用new并且总是在堆栈上(除非它们是实例化的类的成员变量)与new).不过,我一直在阅读信息,这让我怀疑这个长期存在的假设,至少对于Java和C#.
例如,我刚注意到在C#中,new运算符可用于初始化值类型,请参见此处.这是规则的一个例外,该语言的辅助功能,如果是,那么还会有哪些其他例外?
有人可以澄清一下吗?
fre*_*low 25
我认为只有引用类型(类)需要new,而原始类型(int,bool,float等)从不使用new
在C++中,如果要执行以下操作,可以在堆上分配基元类型:
int* p = new int(42);
Run Code Online (Sandbox Code Playgroud)
如果你想要一个共享计数器,这很有用,例如在实现中shared_ptr<T>.
此外,您不必在C++中使用new with class:
void function()
{
MyClass myObject(1, 2, 3);
}
Run Code Online (Sandbox Code Playgroud)
这将myObject在堆栈上分配.请注意,new在现代C++中很少使用.
此外,您可以operator new在C++中重载(全局或特定于类),因此即使您说new MyClass,该对象也不一定在堆上分配.
我不确切地知道Java(并且很难获得有关它的文档).
在C#中,new调用构造函数并返回一个新对象.如果它是值类型,则在堆栈(例如,局部变量)或堆上分配(例如,盒装对象,引用类型对象的成员).如果它是引用类型,它总是在堆上并由垃圾收集器管理.有关详细信息,请参阅http://msdn.microsoft.com/en-us/library/fa0ab757(v=vs.80).aspx.
在C++中,"新表达式"返回指向具有动态存储持续时间的对象的指针(即,您必须自行销毁).在C++标准中没有提到堆(具有这种意义),并且获得这种对象的机制是实现定义的.
无论使用C++或C#还是Java,我的理解始终是当我们使用
new关键字创建对象时,它会在堆上分配内存.
您的理解不正确:
new可能在不同的编程语言中有不同的工作方式,即使这些语言在表面上相似也是如此.不要让C#,C++和Java的类似语法误导你!
术语"堆"和"堆栈"(因为它们在内部存储器管理的上下文中被理解)与所有编程语言无关.可以说,这两个概念更多的是实现细节,而不是它们是编程语言官方规范的一部分.
(IIRC,至少C#和C++都是如此.我不了解Java.)
事实上,它们是如此广泛的实施细节并不意味着你应该依靠这种区别,也不应该知道它!(但是,我承认我通常发现在内部了解"事情如何运作"是有益的.)
我建议你不要过于担心这些概念.你需要做的正确的重要事情是理解语言的语义; 例如,对于C#或任何其他.NET语言,引用和值类型语义的差异.
new:请注意ECMA(第4版)发布的C#规范的以下部分未提及任何"堆栈"或"堆":
14.5.10新运营商
new运算符用于创建类型的新实例.[...]
new运算符意味着创建类型的实例,但不一定意味着动态分配内存.特别是,值类型的实例不需要超出它们所在的变量的额外内存,并且当new用于创建值类型的实例时,不会发生动态分配.
相反,它谈到"动态分配内存",但这不是一回事:你可以动态地在堆栈上,堆上或其他任何地方(例如在硬盘驱动器上)分配内存.
什么是不说的,但是,是值类型的实例存储在原处,这正是价值型语义是一回事:值类型实例分配过程中被复制,而引用类型实例引用/"别名".这是重要的事情要理解,而不是"堆"或"堆栈"!
| 归档时间: |
|
| 查看次数: |
12594 次 |
| 最近记录: |