我的副本构造函数不起作用

时间:2017-09-30 11:30:23

标签: c#

问题已修复!谢谢!

我的副本构造函数似乎无法工作(我已经尝试过我以前用过的相同构造函数):

public Rectangle(Rectangle Rectangle)
{
    bottomleft = Rectangle.bottomleft;
    topright = Rectangle.topright;
}

基本上我有一个名为Rectangle的类,它有两个点(左下角和顶角点 - 矩形与X / Y轴平行/垂直)。

我通过创建一个新的矩形并将新矩形的坐标移动3来测试这个复制构造函数。但是当我对第一个矩形和第二个矩形执行.toString()时,两个坐标都被移动了,而不仅仅是第二个矩形!

这就是我的所作所为:

Point bottom = new Point(0, 0); // a class that stores two 'double' objects (double x, double y)
Point top = new Point(5, 5);
Rectangle first = new Rectangle(bottom,top); // creates new rectangle, horizontal lines are parallel to X axis, vertical are parallel to Y axis

Rectangle second = new Rectangle(first); // attempt to use copy constructor
second.Move(3, 3); // moves the second rectangle three units up and three units to the right
Console.WriteLine(first.ToString()+"\n"+second.ToString()); // posts the coordinates of the two rectangles

第一个矩形的预期输出为(0,0),(5,5),第二个矩形的预期输出为(3,3)(8,8),而输出为(3,3), (8,8)对于两个矩形,意味着两者都被改变了。

如何修复我的复制构造函数(上面发布)?

问题已修复!谢谢! 根据常见的建议,我在“点”上使用了一个复制构造函数。上课也是。我离开这个问题,以防将来帮助某人。

My Point类有一个自己的拷贝构造函数(几乎与我上面发布的一样),我修改了我的Rectangular构造函数,如下所示:

public Rectangle(Rectangle Rectangle) 
    {
        Point a = new Point(Rectangle.GetBottomPoint());
        Point b = new Point(Rectangle.GetTopPoint());
        this.bottomleft = a;
        this.topright = b;
    }

1 个答案:

答案 0 :(得分:1)

如果您制作PointRectangle值类型(struct),则根本不需要复制构造函数:

struct Point { .... }

var p1 = new Point(...);
var p2 = p1; //p2's value is a copy of p1's value
Frob(ref p2);
p2.IsFrobbed; //true
p1.IsFrobbed; //false

c#中的变量由 value 复制,这意味着当您看到类型var p2 = p1的赋值表达式值的副本时存储在p1中的已存储在p2中。

值类型变量中存储的值是值类型 instance 本身,因此p2 = p1创建 new 相同的实例存储在p1中的一个,并将其存储在p2

但是,如果其引用类型变量,则存储的值是实例所在的内存中的地址引用(因此名称)参考类型)。所以,当你执行var p2 = p1时,你正在复制实例的地址,而不是实例本身;因此,p1 p2最终都会引用同一个实例,并且行为会发生根本变化:

class Point { .... }

var p1 = new Point(...);
var p2 = p1; //p2's value is a copy of p1's value
Frob(p2);
p2.IsFrobbed; //true
p1.IsFrobbed; //true!

这是您的问题,Point是一种引用类型,您应该在应该实施时将其设置为值类型(阅读MS's recommendationsthis SO questionthis one作为值类型或引用类型的类型)或实现像Rectangle中那样的复制机制。