返回介绍

11.11 赋值、重命名与拷贝

发布于 2020-09-09 22:55:49 字数 1432 浏览 1093 评论 0 收藏 0

声明一个类变量仅仅产生一个名字,这个名字表示了一个对象。因此:

Packet p1;

上面的例子产生了一个变量,p1,它保存了一个类型为Packet的类对象的句柄,但p1的初始值为null。在Packet类型的一个实例被产生之前,对象并不存在,并且p1没有包含一个真实的句柄:

p1 = new;

因此,如果声明了另外一个变量,并且将先前的句柄赋值为新的句柄,就像下面的例子所示:

Packet p2;
p2 = p1;

那么,仍然只有一个对象,它可以使用p1p2引用。注意:new仅仅执行一次,所以只产生了一个对象。

然而,如果上面的例子按如下的方式重写,那么会产生一个p1的拷贝:

Packet p1;
Packet p2;
p1 = new;
p2 = new p1;

最后一条语句使得new第二次执行,因此产生了一个新的对象p2,它的类属性拷贝自p1。这种方式的拷贝被称作浅拷贝(shallow copy)。所有的变量都被拷贝:整数、字符串、实例句柄等。然而其中包含的对象没有被拷贝,拷贝的是它的句柄;与前面的例子一样,产生了相同对象的两个名字。即使类声明中包含了操作符new的实例化的时候也是如此:

class A;
    integer j = 5;
endclass

class B;
    integer i = 1;
    A a = new;
endclass

function integer test;
    B b1 = new;    // 产生一个B类的对象
    B b2 = new b1; // 产生一个拷贝自b1的对象
    b2.i = 10;     // i在b2中改变,然而在b1中没有改变
    b2.a.j = 50;   // 改变a.j,为b1和b2共享
    test = b1.i;   // test被设置成1(b1.i没有改变)
    test = b1.a.j; // test被设置成50(a.j已经改变了)
endfunction

有几件事需要注意。第一,类属性和实例对象可以直接在类声明中初始化。第二,shallow copy不会拷贝对象。第三,在需要的时候实例限定可以被串接起来以便到达对象或通过对象到达:

b1.a.j               // reaches into a, which is a property of b1
p.next.next.next.val // 通过一系列句柄的串接来获得val

为了实现完整(深度)拷贝,其中每一个东西(包括嵌套的对象)都被拷贝,典型情况下需要定制代码。例如:

Packet p1 = new;
Packet p2 = new;
p2.copy(p1);

其中copy(Packet p)是一个定制的方法,它用来拷贝作为参数传递给它的实例的对象。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文