ここから本文です

C言語 オブジェクトを引数として受け渡す場合、参照型?値型?

cgn********さん

2014/4/2921:50:25

C言語 オブジェクトを引数として受け渡す場合、参照型?値型?

C#にて

データを格納するクラス DataClass
計算するクラス CalcClass

があり、それぞれ、オブジェクトDataA CalcA を作成するとします。

DataClassは、値の合計を保持する変数sumを持っていて
CalcClassは、データを足し合わせるメソッドadd()を持っているとします。

DataAを CalcA.add()に受け渡し計算する場合、

参照型として引き渡されるのか
(メソッド内でsumに結果を書くと、オブジェクトDataA.sum に反映される)
値型として引き渡されるのか
(メソッド内でsumに結果を書いても、オブジェクトDataA.sum に反映されない)
どっちでしょうか

また、C++で同じようなプログラムを書いた場合はどちらになるのでしょうか。

C#のプログラムをC++に移植したところ
C#だと参照型、C++だと値型で引き渡されるような感じなのですが。

//////////////////////////////////////////

class DataClass
{
public int a;
public int b;
public int sum;
}

class CalcClass
{
public void add(DataClass Data)
{
Data.sum=Data.a+Data.b)
}
}

main
{

static DataClass DataA= new DataClass();
static CalcClass CalcA= new CalcClass();

DataA.a=1;
DataA.b=2;
DataA.sum=0;

CalcA.add(DataA);

}

////////////////////////////////////////////////////

としたとき、DataA.sumの値は、3になるのか、0になるのか?

補足C#のオブジェクトは参照型のため、
値渡しでも、元のデータが変更されてDataA.sum=3になるのですね。
謎が解けました。

ちなみに、C++のオブジェクトは値型であり、
値渡しでは、元のデータが変更されずDataA.sum=0
CalcA.add(&DataA);と参照渡しとすればDataA.sum=3
ということでよろしいでしょうか。

閲覧数:
5,073
回答数:
4
お礼:
100枚

違反報告

ベストアンサーに選ばれた回答

liv********さん

編集あり2014/4/2923:29:15

参照型/値型の話と参照渡し/値渡しの話がゴッチャになってるみたいだね。
C#では、クラスから作られたオブジェクトは参照型。
構造体のオブジェクトは値型。
参照型と言うのは、C/C++ でいうところのポインタだね。
つまり、C# の
DataClass d = new DataClass();
は、C/C++ での、
DataClass *pd = new DataClass();
に相当し、d にオブジェクトが格納されているのではなく、d はオブジェクトへの参照(ポインタ)となっている。
次に、参照渡しと値渡しだけど、C#ではref をつけると参照渡しになり、つけないと値渡しになる。
Add(DataClass d)
だと参照型の値渡しになる。
d は参照なので、Add の中で d.Sum に変更を加えると、呼び出し元の方にも反映される。
だけど、Add の中で、
d = new DataClass();
のような付け替える処理をしても、それは呼び出し元には反映されない。
(値渡しだから。)
Add(ref DataClass d)
のようにすると、参照型の参照渡しになり、
Add の中で、
d = new DataClass();
のような付け替えを行うと呼び出し元にも反映される。
参照型の参照渡しは、C/C++ での
Add(DataClass **ppd)
に相当する。(ポインタのポインタ渡し)


追記
>C++のオブジェクトは値型であり

C++には値型とか参照型という考え方はないんだけど、C# 風に言えばそういうことになるのかな。

この回答は投票によってベストアンサーに選ばれました!

ベストアンサー以外の回答

1〜3件/3件中

並び替え:回答日時の
新しい順
|古い順

プロフィール画像

カテゴリマスター

n2q********さん

編集あり2014/4/3012:07:51

引数に渡された時にそれが「参照」になるのか「値」になのか。

C# の場合…クラスなら参照、構造体なら値
C++の場合…宣言子に & があれば参照、そうでなければ値

ということなのです。なお、話を簡単にするためにポインタのことは別としますよ。

《参照》

(1)C#の場合

C# で、次のようにしてみます。

struct DataClass
{
public int a;
public int b;
public int sum;
}

メイン関数では、

DataClass DataA;
CalcClass CalcA= new CalcClass();

DataA.a=1;
DataA.b=2;
DataA.sum=0;

CalcA.add(DataA);

こうします。そしたら、『DataA.sumの値は、3になるのか、0になるのか?』

0 ですよね。DataClass を構造体にしたからです。クラスは参照型、構造体は値型。

(2)C++の場合

C++ だと、struct と class の違いはアクセス指定のデフォルトが public なのか private なのかという違いがあるのみで、あとは一緒。本質的にまったく同じものです。

class DataClass
{
public: int a;
public: int b;
public: int sum;
};
class CalcClass
{
public: void add(DataClass& Data)
{
Data.sum=Data.a+Data.b;//)
}
};
int main()
{
DataClass DataA;
CalcClass CalcA;

DataA.a=1;
DataA.b=2;
DataA.sum=0;

CalcA.add(DataA);

return 0;
}

ここで、

void add(DataClass& Data)
void add(DataClass Data)

の、どちらにするか。& 有りか無しか。それで参照なのか値なのかが切り替わるイメージです。

(3)C# の ref と C++ の &

両者は似ていますが、微妙に違います。

C# の場合、構造体に対して ref を使えば、C++ の & と同じ効果が得られます。でも、クラスに対して使うとまた別の意味合いになります。

C# と C++ の関係についてご興味がおありでしたら、C++/CLI についても調べてみるとおもしろいと思いますよ。C++/CLI は C++ に「参照型」、「値型」の概念を追加していますからね。C# の仕組みの理解にも役立つと思います。ただし、本格的に C++/CLI をやろうとすると、ものすごく難しいです。

k03********さん

2014/4/2922:51:16

cgnqj902さん

C++でコンパイルするとエラー。
コンパイルできるものを書く。

みんなで作る知恵袋 悩みや疑問、なんでも気軽にきいちゃおう!

Q&Aをキーワードで検索:

Yahoo! JAPANは、回答に記載された内容の信ぴょう性、正確性を保証しておりません。
お客様自身の責任と判断で、ご利用ください。
本文はここまでです このページの先頭へ

「追加する」ボタンを押してください。

閉じる

※知恵コレクションに追加された質問は選択されたID/ニックネームのMy知恵袋で確認できます。

不適切な投稿でないことを報告しました。

閉じる