C#初心者です。
最近疑問に思ったことなのですが、
C#にはなぜコピーコンストラクタが存在しないのでしょうか。
C++では
参照型のデータの整合性を保つため、
メモリの多重解放を防ぐために
コピーコンストラクタで対策をすると思います。
(参考にさせてもらったページ)
C#では
プログラマ自身がメモリの解放処理を書くことは無いのですが、
データの整合性を保つためという点においては
コピーコンストラクタがあれば便利だと思います。
以下は考えるのに使ったコードです。
C#
1using System; 2 3public class Program 4{ 5 public static void Main() 6 { 7 // 構造体(値型)のインスタンスを生成する 8 var hoge = new Hoge { foo = new Foo(100) }; 9 10 // このままの状態で値を確認してみる 11 Console.WriteLine(hoge.foo.x); 12 13 // 関数に値渡しをしてから 14 // 値を変更させてみる 15 func(hoge); 16 17 // 値をもう一度確認してみる 18 Console.WriteLine(hoge.foo.x); 19 } 20 21 public static void func(Hoge hoge) 22 { 23 // コピーコンストラクタが呼ばれて 24 // hoge.foo = new foo(); のような処理によって 25 // hoge.fooのメモリを新しく確保させて 26 // 渡された元のメンバには 27 // なんの影響も与えさせないようにさせたいな… 28 // でもコピーコンストラクタが言語仕様に存在しないな… 29 30 // 渡された元のメンバと 31 // 同じものを参照しているから 32 // ここで値を書き換えると 33 // 元の方にも影響が出てしまう… 34 hoge.foo.x = 200; 35 Console.WriteLine(hoge.foo.x); 36 37 // ここで仮引数のhogeの寿命は終わってしまう 38 // もしC++なら 39 // newで確保したメモリはdeleteで解放する必要がある 40 // もしデストラクタでメモリの解放処理を行っているのであれば 41 // hogeの寿命が終わるのでメモリの解放処理が呼ばれると思う 42 // もし、hoge.fooのメモリをここで解放してしまうと 43 // 元のhoge.fooが指しているものもメモリ解放されてしまう… 44 // 幸いこのコードはC#で書かれているため 45 // そんなことは起こらないのだが… 46 } 47} 48 49// 値型 50public struct Hoge 51{ 52 // 参照型のメンバを持つ 53 public Foo foo; 54} 55 56// 参照型 57public class Foo 58{ 59 public int x; 60 public Foo(int x) { this.x = x; } 61}
出力結果はこうなりました。
100 200 200
やはり渡された元のインスタンスのメンバに
影響を与えているようです。
このようなことを防ぐために
Clone()メソッドのようなものを実装するという方法がありますが、
これは言語仕様で強制的に使わないといけないというものではないため
プログラマが忘れればやはり
あのようなバグの原因になるうるコードになります。
このようなことから
私はC#にコピーコンストラクタが存在していても良いと思ったのですが、
なぜ言語仕様に存在しないのでしょうか。
初心者すぎる質問ですいません…
追記
構造体のメンバにクラスを含める事自体が根本的に間違っているというか
状況としては少ないということに気づきました。
回答3件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。