70

Java が C++ のようなコピー コンストラクターをサポートしないのはなぜですか?

4

9 に答える 9

134

Javaはそうします。それらはC ++のように暗黙的に呼び出されるわけではなく、それがあなたの本当の質問だと思います。

まず、コピー コンストラクターは次のようなものです。

public class Blah {
  private int foo;

  public Blah() { } // public no-args constructor
  public Blah(Blah b) { foo = b.foo; }  // copy constructor
}

これで、C++ は次のようなステートメントで暗黙的にコピー コンストラクターを呼び出します。

Blah b2 = b1;

そのインスタンスでのクローン作成/コピーは、Java ではまったく意味がありません。なぜなら、すべての b1 と b2 は参照であり、C++ のような値オブジェクトではないからです。C++ では、そのステートメントはオブジェクトの状態のコピーを作成します。Java では、単に参照をコピーします。オブジェクトの状態はコピーされないため、コピー コンストラクターを暗黙的に呼び出しても意味がありません。

それだけです。

于 2009-05-06T02:50:01.177 に答える
14

ブルース・エッケルより:

[コピー コンストラクター] が Java ではなく C++ で機能するのはなぜですか?

コピー コンストラクターは、オブジェクトのローカル コピーを自動的に作成するため、C++ の基本的な部分です。しかし、上記の例は、Java では機能しないことを証明しています。なんで?Java では操作するものはすべてハンドルですが、C++ ではハンドルのようなエンティティを持つことができ、オブジェクトを直接渡すこともできます。それが C++ コピー コンストラクターの目的です。オブジェクトを取得して値で渡し、オブジェクトを複製する場合です。したがって、C++ では問題なく動作しますが、このスキームは Java では失敗することに注意してください。使用しないでください。

(ページ全体を読むことをお勧めします。実際には、代わりにここから始めてください。)

于 2009-05-06T02:48:11.057 に答える
10

これに対する答えは非常に興味深いと思います。

1 つには、Java ではすべてのオブジェクトがヒープ上にあり、ポインターはありませんが、「参照」はあると思います。参照にはコピー シマンティクスがあり、Java は参照カウントを内部的に追跡するため、ガベージ コレクターは安全に削除できるものを認識できます。

コピー可能な参照を介してのみオブジェクトにアクセスするため、オブジェクトをコピーする必要がある実際の回数は大幅に削減されます (たとえば、C++ ではオブジェクトを関数に (値によって) 渡すだけで、Java では新しいオブジェクトがコピー構築されます)。オブジェクトへの参照のみが渡されます)。設計者は、残りの用途には clone() で十分だと考えたのでしょう。

 

于 2009-05-06T02:45:49.063 に答える
2

これはあくまで私の意見です(正当な答えがあると確信しています)

C++ のコピー コンストラクターは、コピー コンストラクターが透過的にアクティブ化されるため、値によってクラスのインスタンスを送信または返す場合に主に役立ちます。

Java ではすべてが参照によって返され、VM は動的割り当てに対応しているため、コピー コンストラクターの複雑さを正当化する理由はありませんでした。

さらに、すべてが参照によるものであるため、開発者は多くの場合、フィールドを複製する方法について独自の実装と決定を提供する必要があります。

于 2009-05-06T02:46:21.077 に答える
1

代わりに clone() メソッドを作成するだけでよいと彼らは考えたのでしょうか?

于 2009-05-06T02:39:00.873 に答える
0

それは一種のことです。浅いコピーで問題ない場合は [clone()]( http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Object.html#clone())があり、そうでない場合は ' C++ と同じようにディープ コピーを実装する必要があります。

唯一の実質的な違いは、それが適切なコンストラクターではなくファクトリ メソッドであることですが、柔軟性とテスト容易性の観点からは、おそらく良いことです。

于 2009-05-06T02:46:32.463 に答える
0

私はあまり C++ プログラマーではありませんが、コピー コンストラクター、代入演算子、およびデストラクターという "3 つのアミーゴ" に関する規則を覚えているようです。1 つある場合は、3 つすべてが必要になる可能性があります。

言語にデストラクタがなければ、コピー コンストラクタを含めたくないのではないでしょうか? 推測です。

于 2009-05-06T02:47:52.023 に答える
-1

Javaにはコピー コンストラクター があります
注: demo d2=new demo(d1)の代わりに、 demo d2= d1と書くことができます
主な違い b/w two
demo d2=new demo(d1)は、新しいオブジェクトが作成され、メモリが割り当てられることを意味します しかし
demo d2=d1は、オブジェクトd1と 同じメモリ アドレスを使用する参照変数のみが作成されることを意味するため、d2には個別のメモリが割り当てられません。

コピー コンストラクターの構文:
以下を参照してください。最初の例 コピー コンストラクターは非常に簡単です :))
classname(int datafield) //Simple Constructor
{
this.datafield=datafield;
}

classname(classname object)
{
datafield=object.datafield;// 以下の例を参照してください
}
今すぐ呼び出す
{

クラス名 obj=新しいクラス名();

classname anotherObject=obj;// または classname anotherObject=new classname(obj)

}

 クラスのデモ
{
    プライベート int の長さ。

    プライベート int 幅。

    プライベート int 半径;

    デモ (int x,int y)

    {
        長さ=x;
        幅=y;
    }
    int エリア()
    {
        長さ*幅を返します。
    }

    //コンストラクタをコピー
    demo(デモ obj)
    {
        長さ=obj.長さ;
        幅=obj.幅;
    }


    public static void main(String args[])
    {
        デモ d1 = 新しいデモ (5,6);
        demo d2=new demo(d1);// コピー構成を呼び出します
        System.out.println("d1 オブジェクトの領域="+d1.area());
        System.out.println("d2 オブジェクトの領域="+d2.area());

    }
}

于 2013-07-07T22:31:33.703 に答える