我一直在使用c ++,我正在学习java,
在java中声明对象让我感到困惑,
在java中我们写
myclass myobject = new myclass();
myobject.mymethod();
与c ++中的此代码相同吗?
myclass *myobject = new myclass();
myobject->mymethod();
即在heap
分配的内存是什么?如果它在堆上,为什么我们永远不会释放内存。我相信新关键字是一样的。
如果是这样,我们如何在堆栈上分配内存?
答案 0 :(得分:3)
与c ++中的此代码相同吗?
是。它是一样的。
即内存是否在堆上分配?
是的。
如果它在堆上,我们永远不会释放内存。
当对象无法访问时,允许该对象进入垃圾回收器。即没有对该对象的有效引用或(取消引用)
如果是这样,我们如何在堆栈上分配内存?
当特定线程执行开始时,与该线程相关的变量将被放置在堆栈上,并在该线程的作业完成后立即删除。每个线程都拥有它自己的堆栈。
答案 1 :(得分:1)
如您所想,new
运算符在堆上分配新对象。 Java中的内存未被显式释放 - 一旦对象没有更多的访问根,它就有资格被释放。垃圾收集线程会定期释放这个内存。
答案 2 :(得分:0)
虽然说这个C++
代码是等价的并不是不准确的:
myclass* myobject = new myclass();
myobject->mymethod();
它也不完全一样。
Java有一个垃圾收集器,因此,正如您所注意到的,您不必在Java
中释放该对象。
因此可以更接近原始Java
:
std::shared_ptr<myclass> myobject = std::make_shared<myclass>();
myobject->mymethod();
现在,当不再有任何对它的引用时,您不必解除分配myobject
垃圾收集。
但是C++
为每个堆分配的对象使用std::shared_ptr会是错误的,因为它确实会降低性能。
通常,最好使用std::unique_ptr在一个地方管理堆分配对象。如果无法知道哪个组件将是最后一个取消引用该对象的组件,则应在每个位置使用std::shared_ptr。
但是当从持有智能指针的组件调用 down 到函数时,你应该传递原始指针或引用:
std::shared_ptr<myclass> myobject = std::make_shared<myclass>();
myobject->mymethod();
ptr_needing_func(myobject.get()); // pass raw pointer using get()
ref_needing_func(*mtobject.get()); // pass reference using *get()
这样,您在保持垃圾收集智能指针的安全性和便利性的同时,不会失去任何效率。
答案 3 :(得分:0)
在阅读了这个问题和其他一些文章的其他答案后,我明白了,
c ++和java代码都做了非常类似的事情,除了语法不同,java使用引用而不是指针(Java没有指针)。
下面,
myclass myobject;
是myobject的声明,
声明只是通知编译器我们将使用myobject来引用类型为myclass的变量。它没有分配内存。
new myclass();
实例化对象(在堆中分配内存)并返回对它的引用。
通过调用构造函数myclass()来初始化对象。
澄清一个非常基本的疑问,
int i;
==&gt;在堆栈中声明对象并为其分配内存。
myclass myobject;
==&GT;仅声明对象的引用变量(它还需要4个字节或8个字节,具体取决于系统)。它不会分配存储实例变量的实际内存。
换句话说,在声明原始数据类型时分配存储器,但不为非原始数据类型分配存储器。对于非原始数据类型,我们需要使用new关键字分配它们。
为什么我们永远不释放记忆?
Java有垃圾收集器,可以自动为我们完成。
我们如何为堆栈中的对象分配内存?
我们不能。只有原始数据类型可以存储在堆栈中。