使用引用用Java模拟c++指针
Simulating C++ pointers with Java using References?
那么,我有一个整数数组
Integer[] distances = new Integer[n];
然后,我有一个节点的优先级队列,其中的结构包含一个"到"answers"距离",可按距离排序。
class Node implements Comparable<Node>{
Integer distance;
int to;
Node(int To, Integer Dist){
to = To;
distance = Dist;
}
@Override
public int compareTo(Node o) {
if(this.distance < o.distance)return -1;
if(this.distance > o.distance) return 1;
return 0;
}
}
我想做的是像下面这样将节点添加到优先级队列中:
PriorityQueue<Node> q = new PriorityQueue<Node>();
q.add(0, distances[0]);
现在,我想改变dist[0]
的值,并在PriorityQueue中的Node对象中得到反映。第一个问题:因为我在构造函数中传递了一个Integer,它是否会通过引用传递,并且具有类似于使用c++指针的功能:
class Node {
int* distance;
int to;
Node(int To, int* dist){
distance = dist; to = To;
}
,我创建节点为int[] distances = new int[n]; Node nd = new Node(0, &distances[0]);
所以当我改变distances[0]
时,我的*nd.distance
也会改变。
第二个问题:如果可能的话,这是一个很好的做法,或者是否有任何可能性,在我的优先级队列被处置之前,数组被垃圾收集器处置?
正如在注释中已经指出的那样,您的尝试将失败,因为Integer对象是不可变的。我仍然想发布一个非不可变对象的答案,它将指出与c++指针的关键区别。
对第一个问题的简短回答:对于"正常"(非不可变)对象,它将具有类似的功能,但不是完全相同。
在Java中,函数接收对象引用的副本。严格来说,这使得它是按值传递的。下面的示例将演示与c++指针的关键区别。
public class Main {
public static class Test {
public String text;
public Test(String text) {
this.text = text;
}
public void doit() {
System.out.println(text);
}
}
static void reference() {
Test[] t = {new Test("This is class 0"), new Test("This is class 1")};
attemptSwitch(t[0], t[1]);
System.out.println();
System.out.println("calling t[0].doit() outside attemptSwitch():");
t[0].doit();
System.out.println("calling t[1].doit() outside attemptSwitch():");
t[1].doit();
manipulate(t[0]);
manipulate(t[1]);
System.out.println();
System.out.println("calling t[0].doit() after manipulate()");
t[0].doit();
System.out.println("calling t[1].doit() after manipulate()");
t[1].doit();
}
static void attemptSwitch(Test t0, Test t1) {
Test tmp = t0;
t0 = t1;
t1 = tmp;
System.out.println("calling t0.doit() from inside attemptSwitch():");
t0.doit();
System.out.println("calling t1.doit() from inside attemptSwitch():");
t1.doit();
return;
}
public static void manipulate(Test t) {
t.text = "This class has been manipulated!";
}
}
上面的类将首先创建一个包含两个Test
对象的数组。然后它将尝试切换attemptSwitch()
中的这些对象,之后它将尝试通过调用mainpulate()
来更改text
的内容。输出如下所示:
calling t0.doit() from inside attemptSwitch():
This is class 1
calling t1.doit() from inside attemptSwitch():
This is class 0
calling t[0].doit() outside attemptSwitch():
This is class 0
calling t[1].doit() outside attemptSwitch():
This is class 1
calling t[0].doit() after manipulate()
This class has been manipulated!
calling t[1].doit() after manipulate()
This class has been manipulated!
可以看到,在attemptSwitch()
内部的开关是成功的,但是这个开关不是持久的。在函数attemptSwitch()
之外,引用完全不受影响,Test
对象也没有切换。这是因为attemptSwitch()
只接收到Test
对象引用的副本。只有那些副本在函数内部被交换。
如对manipulate()
的调用所示,可以持久地更改类的内容。在这种情况下,函数接收只是引用的副本并不重要,因为它也指向类存储其内容的相同地址。
关于你的第二个问题,我使用了类似的结构。这种方法可能更容易产生内存泄漏,即在内存中保留对象的时间比需要的时间长,而不是丢失数据。只要至少有一个引用指向你的对象,它就不会被垃圾收集——如果引用不是弱引用或类似的东西。优先队列使用常规引用
- 1d 智能指针不适用于语法 (*)++
- 在C#中处理C++指针而不使用unsafe的最佳方法
- 为什么使用 "this" 指针调用派生成员函数?
- 函数向量_指针有不同的原型,我可以构建一个吗
- 使用指针从C++中的数组中获取最大值
- 助记符和指向成员语法的指针
- 嵌入方指针压缩已禁用
- 数组的指针从不分段故障
- C++ 指针的内存地址和指向数组的内存地址如何相同?
- 何时在引用或唯一指针上使用移动语义
- QMetaObject invokeMethod的基于函数指针的语法
- 如何从 std::atomic 中提取指针 T<T>?
- 如何在 C# 中映射双 C 结构指针?
- C++将浮点指针值舍入为小数位数
- 为什么++(*p)更改指针值
- 调整大小后指向元素值的指针unordered_map有效?
- 正在将指针转换为范围
- 使用指向成员的指针将成员函数作为参数传递
- 将OpenCV C++重写为EmguCV C#-如何使用指针
- C++-试图将函数指针推回到另一个CPP文件中的矢量时出错