close

類別物件的複製:

(1) 設今有person類別如下:

class person

{

      public string name;

      public int age;

      public person(string n_, int a_)  //建構式在此

      { name = n_; age = a_; }

      public string self_introduction()

            { return "hi, I'm " + name + "," + age + "years old."; }

};

且已宣告一個person類別物件p1

person p1 = new person("weiwei", 18);

那麼要如何複製p1呢?

並不是只用person p2 = p1;就可複製p1,因為C#類別物件事實上只是個參考,並非實體。也就是說,p2p1參考同一個物件,所以改變p2的同時也會改變p1。證明如下:

            person p1 = new person("weiwei", 18);

            person p2 = p1;

            p2.name = "nunu";

            richTextBox1.Text = p1.name.ToString();

則程式執行完成後,richTextBox1.Text之值會是nunu

(2) 要在C#中執行真正的複製,也就是複製一個與原先物件有相同成員值、成員函數,但互相獨立、彼此互不影響的物件,必須用「深複製(deep copy)」方法。也就是說在類別中自寫一個函式,可回傳一個相同類別物件,而此類別物件與本物件一模一樣。如在person類別中,寫下deep_copy()函式

                  public person deep_copy()

            {

                person new_person = new person(this.name, this.age);

                return new_person;

            }

然後:

            person p1 = new person("weiwei", 18);

            person p2 = p1.deep_copy();

            p2.name = "nunu";

            richTextBox1.Text = p1.name.ToString();

則程式執行完成後,richTextBox1.Text之值還是weiwei

(3) 深複製並非只有這麼簡單,若碰上更複雜的類別,那就會變得更麻煩。如在上例中再加上一個kingdom類別:

class kingdom

{

public person king;

public person queen;

public List<person> worker = new List<person>();

public string name;

public string history;

public int money;

public kingdom(string name_)

{ name = name_; }           

}

那麼在寫深複製函式之前,要先搞清楚哪些成員是類別物件,要先為這些成員寫深複製函式才行。kingdom類別的深複製函式如下:

            public kingdom deep_copy()

            {

                kingdom new_k = new kingdom(this.name);

                new_k.king = this.king.deep_copy();

                new_k.queen = this.queen.deep_copy();

                new_k.worker = this.worker.ToList();

                new_k.history=this.history;

                new_k.money = this.money;

                return new_k;

            }

然後利用下列程式碼測試:

            kingdom k1 = new kingdom("AAA");

            k1.king = new person("king.AAA", 50);

            k1.queen = new person("queen.AAA", 40);

            k1.worker.Add(new person("w1.AAA", 20));

            k1.worker.Add(new person("w2.AAA", 25));

            k1.history = "AAA's history";

            k1.money = 100;

 

            kingdom k2 = k1.deep_copy();

            k2.king = new person("king.BBB", 50);

            k2.queen = new person("queen.BBB", 40);

            k2.worker.Add(new person("w1.BBB", 20));

            k2.worker.Add(new person("w2.BBB", 25));

            k2.history = "BBB's history";

            k2.money = 200;

 

            richTextBox1.Text +=

            "k1:king = " + k1.king.name + "\r\n" +

            "k1:queen = " + k1.queen.name + "\r\n" +

            "k1:worker = ";

            for (int i=0;i<k1.worker.Count;i++)

            {

                richTextBox1.Text +=k1.worker[i].name+",";

            }

            richTextBox1.Text += "\r\n" +

            "k1:history = " + k1.history + "\r\n" +

            "k1:money = " + k1.money + "\r\n";

則程式執行完成後,richTextBox1.Text之值為:

k1:king = king.AAA

k1:queen = queen.AAA

k1:worker = w1.AAA,w2.AAA,

k1:history = AAA's history

k1:money = 100

這代表深複製函式的成功。

 

 

 

上一篇:靜態成員與靜態成員函式

下一篇:類別的繼承

按此前往C#完整教學目錄

arrow
arrow
    創作者介紹
    創作者 埃伯 的頭像
    埃伯

    程式語言教學

    埃伯 發表在 痞客邦 留言(0) 人氣()