C++とその他言語における値渡し・参照渡し

アバター
MoNoQLoREATOR
記事: 284
登録日時: 14年前
住所: 東京

C++とその他言語における値渡し・参照渡し

投稿記事 by MoNoQLoREATOR » 12年前

まず次の2つの記事をご覧ください。
値渡しと参照渡し (と参照の値渡し)
関数の引数の値渡しと参照渡し

C++,Java,C#,ActionScriptの値渡し・参照渡しについて確認ができたことと思います。
値渡し・参照渡しの仕様は、その言語の特徴や考え方を最も顕著に表現するものだと私は考えています。
オブジェクト指向が前提の言語は、クラスのインスタンスがデフォルトで参照渡しとなっている傾向があるようです。
たしかにそこだけ見れば理に適っていると思います。
値渡しよりも参照渡しをする機会の方が圧倒的に多いことが予想されるからです。
しかし、プリミティブ型とリファレンス型でデフォルトの動作が異なるというのは混乱を招くことに他ならないのではないでしょうか。
例えば型を変更する必要が生じたとします。
それがプリミティブ型とリファレンス型の変更であった場合、ソースコードを大幅に書き換える必要が出てくる可能性も十分あるでしょう。
同じ理由で、C++のtemplateのようなこともできません。
また、プリミティブ型を参照渡ししたい場合や、参照の参照を行いたい場合は工夫が必要です。
以上のことから、私はC++方式を支持します。
しかし、C++の「参照」では参照先を変更するということができません。
そこで、代わりにポインタを使うことになります。
ただしポインタ演算を行う必要があるため、あまり直観的ではありません。
ゆえに私の理想と完全にマッチする値渡し・参照渡しを採用している言語は今のところ見つかっていません。(C++が最も近いことは確かです)

そこで、以前にも話したと思いますが、「コネクション」という新しい概念を提案します。
"普段は参照先のインスタンスそのものとして扱い、参照先を設定/変更する時のみコネクションであることを意識して取り扱う"
そういった概念がコネクションです。
これにより厳密性を保ちながら、より直感的なソースコードを実現することができます。

CODE:

int $ intcon0;    // 宣言。参照先はnullに設定される
++intcon0;    // 参照先がnullの状態でインスタンスにアクセスすると ぬるぽ!ランタイムエラーが発生する

int value0;
int $ intcon1(value0);    // 宣言と同時に参照先を設定する
int value1;
intcon1 $= value1;    // 参照先を変更

// コネクションのコネクション(以下ダブルコネクション)
int val0(0);
int val1(1);
int $ con(val0);
//int $$ concon(con);    // 参照先には必ずコネクションを設定 ※訂正↓
int $$ concon($con);    // 参照先がシングルコネクションであることを明示する必要がある
con $= val1;
printf("%d", con);         // 1
printf("%d", concon);    // 1

// これと同じ原理で、トリプルコネクションやクアドラプルコネクション等も使用可能です。
// ただし必ず、トリプルコネクションの参照先にはダブルコネクション、クアドラプルコネクションの参照先にはトリプルコネクション…と設定する必要があります。
// つまり未設定の状態は許されていません。

// また、自分よりも小さいコネクションにキャストすることもできます。
int $$$$ quadruplecon(c);    // c等の宣言は省略
int $$$ triplecon($$quadruplecon);
int $$ doublecon($triplecon);
// このように、コネクション名の前にダラーを付けるとキャストになります。
// $でシングルコネクションへ、$$でダブルコネクションへ、$$$でトリプルコネクションへ…とキャストされます。
ポインタはメモリの位置をメインに取り扱うのに対し、コネクションはインスタンスをメインに取り扱います。
よって普段はコネクションであるということを意識する必要はありません。
これは非常に大きな利点であると私は思います。
また、ポインタはポインタ演算によってダブルポインタからトリプルポインタに切り替えたりしますが、コネクションはそもそも考え方が違います。
キャストによって、どこを参照するのかを指定します。
「何回ポインタ演算すればよいのか」などと考える必要はありません。
「ダブルコネクションにキャスト」とストレートに指定することができるのです。


ぜひみなさんの意見をお聞きしたいです。
感想だけでもありがたいのでコメントよろしくお願いします。
最後に編集したユーザー MoNoQLoREATOR on 2013年3月10日(日) 13:58 [ 編集 3 回目 ]

アバター
MoNoQLoREATOR
記事: 284
登録日時: 14年前
住所: 東京

Re: C++とその他言語における値渡し・参照渡し

投稿記事 by MoNoQLoREATOR » 12年前

>>funcの引数がダブルコネクションを要求する場合はどうなるのですか?

既に仕様に書かれている通りです。
「// ただし必ず、トリプルコネクションの参照先にはダブルコネクション、クアドラプルコネクションの参照先にはトリプルコネクション…と設定する必要があります。」
よってダブルコネクションが要求されているのにダブルコネクションを指定しなかった場合は全てエラーになります。
そのサンプルコードですと正解はこうです。

CODE:

void func(int $$$ cc){}
int $ c;
int $$ cc;
int $$$ ccc;
func($$c);
func($$cc);
func($$$ccc);
>>C++の参照型を示す記号は宣言にしか現れませんからそもそも対称性を持たせる必要がありません。
>>むしろ似せるべき対象じゃないのに似せようとして破綻しているのが現状ですよね。

似せるべきかそれとも対称性を持たせるべきかは悩みました。
確かに対称性を持たせた方がわかりやすかったかもしれません。
しかし破綻はしていませんし、対称性を持たせるか否かで破綻する/しないが変わるものでもありません。


今までお付き合いいただき本当にありがとうございました。
ISLeさんの意図がよくわからなかったことは確かに何回かありました。
おそらく私の理解力が足りないせいです。
多分そのうちわかるようになると思います。
考えが変わったりした日にはまた記事を書くことになるでしょう。