2011-09-25 13 views
7
import std.stdio; 

class IntegerContainer 
{ 
    public int Integer = 1; 
} 

void DoubleInteger(IntegerContainer Container) 
{ 
    Container.Integer *= 2; 
} 

void main() 
{ 
    IntegerContainer Container = new IntegerContainer; // Internal integer defaults to one. 
    DoubleInteger(Container); // Internal integer changes to two inside the function. 
    writefln(Container.Integer); // Prints "2." 
} 

Dでは、参照と値は、functionパラメータではなく型の特性です。 C++から来て、これは私にとって本当に悪いと感じています。値でオブジェクトを渡すにはどうすればよいですか?

を受け入れる関数の参照渡しを強制するキーワードはrefのようです。値段でclassを渡すのと同等のものはありますか?

たとえば、カスタムコンテナクラスのソートされたコピーを返す関数関数を作成したいとしましょう。 C++では、Foo Sort(Foo& Object)ではなく、Foo Sorted(Foo Object)を使用するのと同じくらい簡単です。手動でオブジェクトをコピーすることなく、Dでこれを行う方法はありません。

+1

クラスのオブジェクトであっても、値渡しの参照であるため、まだ値渡しです。 – newacct

+3

@newacct皆が「値渡し」の意味を知っていると思います。 – Maxpm

答えて

11

クラスは設計上の参照型です。彼らは価値あるものになるとは考えられていません。 JavaとC#ではまったく同じです。しかし、JavaやC#とは異なり、Dには構造体(C#も構造体を持っていますが、多くの場合が制限されています)があるので、Dも本格的なユーザー定義の値型を持っています。 C++が2つを融合させるという事実は、object slicingのような問題を引き起こします。

参照タイプをコピーする場合は、明らかにになります。その解決策はcloningです。クラスにはcloneという関数を呼び出し、呼び出されたオブジェクトのコピーを返します。そうすれば、必要なときにコピーすることができます。必要なときにコピーされます。 JavaとC#には標準のclone関数が実装されていますが、何らかの理由でDは実装されていません。なぜ私は分からない。しかし、自分のタイプの関数を宣言するのはまだ簡単です。それはちょうどObjectになる予定ではありません。それは、あなたがJavaやC#でできるような実際のタイプを気にせずに、どんなクラスオブジェクトでも使用できるようにします。コピーコンストラクタは、好きなだけ作成することもできますが、コピーするオブジェクトのタイプを知る必要があるため、柔軟性は低くなりますが、cloneではcloneが返すタイプから派生した任意のタイプになりますJavaとC#の場合はObjectになりますが、関数が非標準であるためDで決定したものになります)。

+1

IIRC D(配列)内のいくつかのものは 'dup'プロパティを持っています。 – BCS

+0

はい、しかし、クラスは通常このような関数を実装しません。しかし、 'clone'ではなく' dup'という関数を実装するのが一般的になりますが(標準ライブラリにはまだクラスがたくさんありませんので、特定のクローン関数がすべての標準はまだ)。いずれにせよ、それは同じ概念です。 –

+0

Ah。はい。私はもっ​​と明確にすべきです:他のものが 'dup'を使っているので、' clone'関数を呼ばないことは良い考えです。名前を同じにしておくと、テンプレートコードがきれいになる場合があります。 – BCS

4

ええ、ちょうどクラスの代わりに構造体を使用してください。

オブジェクトをコピーする場合は、自分で複製を実装する必要があります。 Dデザイナーはこれを作っていないことに注意してください。 C#ではまったく同じ方法であり、Javaではかなり似ています。目標は、オブジェクトが過度にコピーされるのを防ぐことです。これはC++の欠点といえます(コード内に隠されているため)。でもCで

+0

編集を参照してください。 [15char] – Maxpm

+1

@ Maxx:第2段落の第1文を参照してください。 – Mehrdad

3

++この:

Foo Sorted(Foo Object) 

はその有用ではありません。オブジェクトがすでにソートされていて、コピーを作成する必要がない場合はどうなりますか?

Dでは、あなたのクラスにそのようなもののうちclone()を提供し、必要に応じて呼び出す必要があります。

それ以外の場合は、構造体をMehrdadとして使用します。

編集:「オブジェクトをコピーする」が何をすべきかはっきりしません。それがオブジェクトの配列を内部に持っているなら、それはその配列を複製するでしょうか?オブジェクト参照には何が含まれていますか?実際には、Dの著者であるウォルター・ブライトは、デフォルトでクラス・インスタンスのコピーを提供していませんでした。

関連する問題