C++ クラス(というか関数)の初歩なのですが・・・

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
ベル

C++ クラス(というか関数)の初歩なのですが・・・

#1

投稿記事 by ベル » 9年前

初めまして こんにちわ。 閲覧ありがとうございます。

「猫でもわかるC++」の書籍を一通り流し読みをし、なんとなくC++ というものが分かり始めたド素人です。

色んなサイトを見て勉強し、確認用の小さなプログラムを試しに作っていき実践的な勉強をしておりましたが、題名のとおりクラスの部分で躓いてしまったので教えていただきたく書き込みさせていただきます。

以下某”ゲームプログラミング応援サイト”から

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
// クラス定義(.hファイル)
class CTest { //CTestというクラスを定義
protected:    //派生クラスから書き換えできるように(オーバーライド?)protectedアクセス子を指定
int a;     //int型(1バイト)のメモリ領域を確保し、そこは”a”と呼ぶことにする(変数の宣言)
public:       //外部から自由に値をセットできるようにpublicアクセス子を指定
void SetA( int _a ); //void型の(不確定の? 汎用性の高い?)SetAという関数をプロトタイプ宣言 とりあえず"_a"という名前のint型メモリ領域を確保
int GetA( void );  //よく分からない。 int型の関数GetAを宣言。戻り値がvoidということは戻り値がないということ????
};
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
#include "CTest.h"

// 関数の実体(.cppファイル)
void CTest::SetA( int _a )
{                  //CTestというクラスのSetAという関数の(int _a ⇒int aに書き換えられる?)
a = _a;            //つまりこの時点でvoid SetA( int a )ということ???
}                  //だったら初めからvoid SetA( int a )というプロトタイプ宣言をすればよいのでは????
                   //関数なのにreturnなしでもいいの?? コンパイラが関数の終わりを分かりにくいんじゃぁ・・・???
int CTest::GetA( void )
{
return a;            //aという変数を返す? つまりGetA( void )⇒GetA( a )になったということ? でもvoidだったら戻り値は無しじゃないの???
}
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
#include <stdio.h>
#include <conio.h>
#include "CTest.h"

int main( int argc,char *argv[] )     //int型の仮引数およびchar型の仮引数を宣言?? 使わなくてもいい? 宣言した段階ではどれくらいのメモリ領域が
{                         // 必要か不明?? argcやargvというのは定型句であり、特に意味はない??
CTest ct;                  //CTestをインヘリテンス(?)する。 ctという入れ物に入れますよという宣言

ct.SetA( 100 );              //SetA( int a )⇒SetA( 100 )になった。つまりaに100を代入しただけ

printf( "A=%d\n",ct.GetA() );     //ここでGetA関数が出てきた理由が最大の謎。ct.GetA()をct.SetA()に書き換えるとコンパイルエラーになる
                         //SetA中にも(int a = 100)というのが書かれているんじゃないの?
getch();
return 0;
}
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

上記のプログラムコードはサイト様からの完全なコピペで、コメントアウト文は全て私が書きました。

簡単な関数なら解読できますし、自分で使えますが上記のは私にとってはかなりの応用が利いた使い方でちょっと意味が分かりません。

関数名からして
1.SetAという関数で一回(int a)のaの中に100という整数を入れている
2.SetAという関数は「aの値を取得する」ためだけの関数のため、printf関数に渡すために”GetA関数”が必要

という認識でしょうか? 

もしそのとおりなら「SetA関数とGetA関数の二つの機能を併せ持った関数」はどうやって書けばいいのでしょうか?(ここができるかどうかで”関数やクラス”という概念をちゃんと習得できているかのターニングポイントになると思ってます。


なにぶん素人ですので、思い違いをしているかも知れませんが、自分なりの解釈を書くことで正しい知識を持った方に”どこが分かってないか”をご指摘していただけると非常に助かります。

長文失礼いたしました。

アバター
h2so5
副管理人
記事: 2212
登録日時: 9年前
住所: 東京
連絡を取る:

Re: C++ クラス(というか関数)の初歩なのですが・・・

#2

投稿記事 by h2so5 » 9年前

まず関数をよく理解できていないようです。
関数の戻り値と引数が逆になってますよ。
ベル さんが書きました: int GetA( void );  //よく分からない。 int型の関数GetAを宣言。戻り値がvoidということは戻り値がないということ????
戻り値(の型)は int です。引数が voidです。
ベル さんが書きました: // 関数の実体(.cppファイル)
void CTest::SetA( int _a )
{                  //CTestというクラスのSetAという関数の(int _a ⇒int aに書き換えられる?)
a = _a;            //つまりこの時点でvoid SetA( int a )ということ???
}                  //だったら初めからvoid SetA( int a )というプロトタイプ宣言をすればよいのでは????
                   //関数なのにreturnなしでもいいの?? コンパイラが関数の終わりを分かりにくいんじゃぁ・・・???
a = _a; はCTestのメンバ a に引数の _a の値を代入しています。
プリプロセッサじゃあるまいし、置き換えなどしません。

そして戻り値が void なので 値を返してはいけません。当然returnもありません。
ベル さんが書きました:
int CTest::GetA( void )
{
return a;            //aという変数を返す? つまりGetA( void )⇒GetA( a )になったということ? でもvoidだったら戻り値は無しじゃないの???
}
戻り値の型は int です
ベル さんが書きました: printf( "A=%d\n",ct.GetA() );     //ここでGetA関数が出てきた理由が最大の謎。ct.GetA()をct.SetA()に書き換えるとコンパイルエラーになる
                         //SetA中にも(int a = 100)というのが書かれているんじゃないの?
SetA()は値を返しません。

ベル さんが書きました: 関数名からして
1.SetAという関数で一回(int a)のaの中に100という整数を入れている
2.SetAという関数は「aの値を取得する」ためだけの関数のため、printf関数に渡すために”GetA関数”が必要

という認識でしょうか? 
その通りです。
ベル さんが書きました: もしそのとおりなら「SetA関数とGetA関数の二つの機能を併せ持った関数」はどうやって書けばいいのでしょうか?(ここができるかどうかで”関数やクラス”という概念をちゃんと習得できているかのターニングポイントになると思ってます。
関数のオーバーロードを使うか、aのアクセス子をpublicにすればいいと思います。

アバター
bitter_fox
記事: 607
登録日時: 9年前
住所: 大阪府

Re: C++ クラス(というか関数)の初歩なのですが・・・

#3

投稿記事 by bitter_fox » 9年前

まずコードを載せる際はcodeタグで囲っていただきますようにお願いします。

ベル さんが書きました:

コード:

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
// クラス定義(.hファイル)
class CTest {       //CTestというクラスを定義
protected:    //派生クラスから書き換えできるように(オーバーライド?)protectedアクセス子を指定
    int   a;     //int型(1バイト)のメモリ領域を確保し、そこは”a”と呼ぶことにする(変数の宣言)
public:       //外部から自由に値をセットできるようにpublicアクセス子を指定
    void  SetA( int _a ); //void型の(不確定の? 汎用性の高い?)SetAという関数をプロトタイプ宣言 とりあえず"_a"という名前のint型メモリ領域を確保
    int   GetA( void );  //よく分からない。 int型の関数GetAを宣言。戻り値がvoidということは戻り値がないということ????
};
まず、関数に型は有りません、関数の戻り値と引数に型があります。
また、aや_aのことについて「メモリを確保」というのは、ちょっと違ってますね。

関数の宣言は次のようになってます

コード:

戻り値の型    関数名(  引数の型  引数名  ,  引数の型  引数名  ); // 引数は必要な数だけ宣言できる
引数名は実体を宣言するときは必須ですが、プロトタイプ宣言の際は省略可です。
ベル さんが書きました:

コード:

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
#include "CTest.h"

// 関数の実体(.cppファイル)
void CTest::SetA( int _a )
{                  //CTestというクラスのSetAという関数の(int _a ⇒int aに書き換えられる?)
    a = _a;            //つまりこの時点でvoid  SetA( int a )ということ???
}                  //だったら初めからvoid  SetA( int a )というプロトタイプ宣言をすればよいのでは????
                   //関数なのにreturnなしでもいいの?? コンパイラが関数の終わりを分かりにくいんじゃぁ・・・???
int CTest::GetA( void )
{
    return a;            //aという変数を返す? つまりGetA( void )⇒GetA( a )になったということ? でもvoidだったら戻り値は無しじゃないの???
}
まず、SetAですが、そのような書き換えはされません。
これは、aに_aの値を代入しているだけです。
また、この関数の戻り値はvoidでvoidは戻り値がないことを示しますので、returnは無くてもいいです。
後、コンパイラはreturnで関数の終わりを判断してるのではなく{}の対応で関数の終わりを判断しています。

どうやら、引数と戻り値の位置を勘違いしているようです。
ベル さんが書きました:

コード:

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
#include <stdio.h>
#include <conio.h>
#include "CTest.h"

int main( int argc,char *argv[] )     //int型の仮引数およびchar型の仮引数を宣言?? 使わなくてもいい? 宣言した段階ではどれくらいのメモリ領域が
{                         // 必要か不明?? argcやargvというのは定型句であり、特に意味はない??
    CTest ct;                  //CTestをインヘリテンス(?)する。 ctという入れ物に入れますよという宣言

    ct.SetA( 100 );              //SetA( int a )⇒SetA( 100 )になった。つまりaに100を代入しただけ

    printf( "A=%d\n",ct.GetA() );      //ここでGetA関数が出てきた理由が最大の謎。ct.GetA()をct.SetA()に書き換えるとコンパイルエラーになる
                         //SetA中にも(int a = 100)というのが書かれているんじゃないの?
    getch();
    return 0;
}
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
argvにはコマンドライン引数が入れられます。また、argcはその引数の個数です。
インヘリテンスはインヘリタンスの間違いだとしても継承と言う意味なので、実体を意味するインスタンスの間違いじゃないでしょうかでしょうか?

この時100になったのは、クラスCTestのメンバであるaです。

コンパイルエラーになるのは、引数が足りてないからですね。
ここは、GetAを呼ぶことで、それがaの値を返すのでそれをprintfの引数に使用しているわけです。
SetAにそのような機能はありません。
ベル さんが書きました: 関数名からして
1.SetAという関数で一回(int a)のaの中に100という整数を入れている
2.SetAという関数は「aの値を取得する」ためだけの関数のため、printf関数に渡すために”GetA関数”が必要

という認識でしょうか? 

もしそのとおりなら「SetA関数とGetA関数の二つの機能を併せ持った関数」はどうやって書けばいいのでしょうか?(ここができるかどうかで”関数やクラス”という概念をちゃんと習得できているかのターニングポイントになると思ってます。


なにぶん素人ですので、思い違いをしているかも知れませんが、自分なりの解釈を書くことで正しい知識を持った方に”どこが分かってないか”をご指摘していただけると非常に助かります。
SetAは「aの値を取得する」のではなく「aに第一引数の値を代入」する関数ですね。

二つの機能を併せ持った関数と言うのは作れなくはないですが、Set_, Get_で問題ないんじゃないでしょうか・・・
やるなら、関数のオーバーロードでしょうか・・・

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 9年前
住所: 東海地方
連絡を取る:

Re: C++ クラス(というか関数)の初歩なのですが・・・

#4

投稿記事 by softya(ソフト屋) » 9年前

補足的に追加しますとsetとgetに分かれているのは、オブジェクト指向のカプセル化と言う概念を実現するためです。
なので、aをpublicにしたりするのは基本的に避けるべき行為だと思ってください。
それとsetでセットした値を持ち帰ることは出来ますが、そんな関数作って使うのか?と言えば返り値なんて使わないと思います。
だって、引数のままの値が戻ってくるだけなんて意味ないじゃないですか。

こういう関数は、もっとプログラムが大きくなってsetとgetがぜんぜん違う離れたコードの場所にあるようになって意味が出てくるものです。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

ベル

Re: C++ クラス(というか関数)の初歩なのですが・・・

#5

投稿記事 by ベル » 9年前

h2so5様>>
おっしゃるとおりです! 戻り値と引数がごっちゃになってました!

仮引数と実引数があったのでちゃんと覚えたつもりだったのですが・・・ 自分が思っていたよりももっと基本的なことがわかっていなかったようです。

おかげさまでスッキリコードを読むことができました!

プログラムの流れとして、

1.main関数の中でSetA関数を呼び出している(と同時に初期値に100を入れている)
 この時点で

コード:

void CTest::SetA( int _a(中には100が入れられた) )
{			
a = _a;		//_aの中の値の100をaに代入
}			//この関数をわざわざ使っているのは変数aがprivateの中にあるから
	
つまり中の処理が終わると
void CTest::SetA(int _a)
※_aの中身は100
※aの中身も100
という形になっているvoid型のため戻り値は持っていない(aの中に_aを代入しただけの関数だった)

2.GetA関数の処理により

コード:

int CTest::GetA( void )
{
return a;	 //aの変数の中身を返り値にする
}
int(中にはaの中身である100が入っている)CTest::GetA(void)

GetA関数には戻り値がセットされているため、printf関数ではGetA関数が呼ばれた。

ということですよね?

ただ腑に落ちないのはなんで最初のSetA関数の実態を書くときに
void SetA (int _a)
と書いたのかが分からないのです。 void型宣言したがために、戻り値を持てないならなぜ最初からint型で宣言しないのでしょうか?

ちなみに
int SetA(int _a)
で巻数の実態を書いてみると、main関数のほうで”getch”へのエラーが出てしまいました
「 warning C4996: 'getch': The POSIX name for this item is deprecated. Instead, use the ISO C++ conformant name: _getch. See online help for details.」
getchという名前をISOは推奨していない??? ちょっとここが新しい疑問です

ベル

Re: C++ クラス(というか関数)の初歩なのですが・・・

#6

投稿記事 by ベル » 9年前

bitter_fox様>>
あ コードタブの存在を知りませんでした。 すみません 以後気をつけます。

>>また、aや_aのことについて「メモリを確保」というのは、ちょっと違ってますね。
この表現だと”確保した4バイト(int型なので)の領域のアドレスにaを割り当てた”というべきでしょうか? つまり0x000000~0x000032=a みたいな?

>>また、この関数の戻り値はvoidでvoidは戻り値がないことを示しますので、returnは無くてもいいです。
>>後、コンパイラはreturnで関数の終わりを判断してるのではなく{}の対応で関数の終わりを判断しています。

>>どうやら、引数と戻り値の位置を勘違いしているようです。

おっしゃるとおり引数と戻り位置を勘違いしておりました。戻り値とreturnの関係は他の入門サイトを見て理解を深めました。


「void 関数名 (int)」の意味が分からないので、また勉強してみます。 自力で理解できなければ新しいスレッドを立てさせていただくと思いますので、またお力添えをしていただけると助かります。

アバター
h2so5
副管理人
記事: 2212
登録日時: 9年前
住所: 東京
連絡を取る:

Re: C++ クラス(というか関数)の初歩なのですが・・・

#7

投稿記事 by h2so5 » 9年前

ベル さんが書きました: ただ腑に落ちないのはなんで最初のSetA関数の実態を書くときに
void SetA (int _a)
と書いたのかが分からないのです。 void型宣言したがために、戻り値を持てないならなぜ最初からint型で宣言しないのでしょうか?
setA関数はその名のとおり、aに値を代入するための関数なので、
戻り値は必要ないからです。

aの値が欲しければGetAを使えばいいのです。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 9年前
住所: 東海地方
連絡を取る:

Re: C++ クラス(というか関数)の初歩なのですが・・・

#8

投稿記事 by softya(ソフト屋) » 9年前

うーん。カプセル化の話は届いていない?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

ベル

Re: C++ クラス(というか関数)の初歩なのですが・・・

#9

投稿記事 by ベル » 9年前

softya(ソフト屋) 様>>

>>こういう関数は、もっとプログラムが大きくなってsetとgetがぜんぜん違う離れたコードの場所にあるようになって意味が出てくるものです。

ですよね。 初心者にも分かりやすく短いコードで書いてくれてるのは分かるのですが、逆に短すぎてクラスを使う理由がピンとはこないです(praivateの中におくことによって保守性を高めたいというのは分かりますが・・・)

ぶっちゃけ
int a;

int SetA(100);

printf(%d,SetA);

とあんまり変わらないじゃん と思ってしまいます(これは私がクラスという概念をよくわかってないのが悪いのですが・・・)

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 9年前
住所: 東海地方
連絡を取る:

Re: C++ クラス(というか関数)の初歩なのですが・・・

#10

投稿記事 by softya(ソフト屋) » 9年前

ベル さんが書きました: int a;
int SetA(100);
printf(%d,SetA);
とあんまり変わらないじゃん と思ってしまいます(これは私がクラスという概念をよくわかってないのが悪いのですが・・・)
それ、むちゃくちゃ文法的に出鱈目ですよ。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

ベル

Re: C++ クラス(というか関数)の初歩なのですが・・・

#11

投稿記事 by ベル » 9年前

softya(ソフト屋) 様>>
おっとレスしている間にレスをいただいてしまいました ちょっと時間軸がずれてしまってすいません><

カプセル化の話は伺ってますし、参考書などを読み直して理解はしたつもりです。

ただクラスというものを書きなれていないので、どうしてもピンとこないんですよね・・・

int aの値を外部から勝手に書き換えられないように、praivateの中からしかaの値をいじれないのは理解しているつもりですが・・・


これは本を読むより、コードを書いていって、慣れるしかないのかなぁと思ってます。

2つめのレスについて
すいません! 途中でレスをいただいてるのに気づいてあわてて書いてみましたが後から”訂正”や”削除”の仕方が分からなかったためあのままになってしまいました・・・

ちゃんとしたコードを書くのはまだ空では無理で参考書を読みながらじゃないと書けないので、急いで自分のイメージを伝えようとした結果がアレですorz

ベル

Re: C++ クラス(というか関数)の初歩なのですが・・・

#12

投稿記事 by ベル » 9年前

h2so5様>>

へ 返信が早いです! まさかレスしている間にさらにレスがくるとは!!!

んー 関数というものを私がちゃんと理解できていないので混乱しちゃってます・・・

関数というものは自販機のようなもの。 100円を入れるとなんか知らんけどジュースが出てくる。

これは”猫でもわかる~”の書籍で納得しました。 だからこそSetAのような返り値を持たない関数に関してはちょと腑に落ちないのです。 100円入れたけどジュースが出てこないってことではないのか? と思ってしまいます。

私の中で関数というのは

□main関数さん
「SetAちゃん、{a = _a;} という処理をしといて! 初期値あげるね!」
□printf関数さん
「SetAちゃん、Main関数さんの頼まれごとが終わったらこっちに来てくれない? 出力したいからキミの持ってる返り値が欲しいんだよね!」
□SetA関数ちゃん
「わかったー 今行くよー」

という感じで
1.自分の中で決められた処理をする
2.処理の結果を他の人に渡す。

という二つの行動ができるものだという認識です(あくまで私の脳内)。

でも上記のプログラムを見ると

□main関数さん
「SetAちゃん、{a = _a;} という処理をしといて! 初期値あげるね!」
□printf関数さん
「SetAちゃん、Main関数さんの頼まれごとが終わったらこっちに来てくれない? 出力したいからキミの持ってる返り値が欲しいんだよね!」
□SetA関数ちゃん
「え? もう私の仕事は終わったもん。 私は遊びに行くの~ aの中身ならGetA君が知ってるから彼に頼んでくれる?」

みたいな動きしてますよね?
「C++はそういうものだ」と言われればそこで話は終わりなんですが、ちゃんと納得するために必要な”何か”を私は見落としていると思うんですよね・・・

アバター
bitter_fox
記事: 607
登録日時: 9年前
住所: 大阪府

Re: C++ クラス(というか関数)の初歩なのですが・・・

#13

投稿記事 by bitter_fox » 9年前

ベル さんが書きました: >>また、aや_aのことについて「メモリを確保」というのは、ちょっと違ってますね。
この表現だと”確保した4バイト(int型なので)の領域のアドレスにaを割り当てた”というべきでしょうか? つまり0x000000~0x000032=a みたいな?
うーん、まぁ、大体そんな感じですね・・・

ちなみに、0x000000~0x000032=aはちょこっと違いますね。
まず、0xなので一般に16進数なので、後ろの値は
50になってしまいます。
また、0x32としたのは4バイトが32ビットになることからかと思いますが、メモリのアドレスは、一ビット単位ではなく、一バイト単位ですので、
0x00~0x03になります。
ベル さんが書きました:「void 関数名 (int)」の意味が分からないので、また勉強してみます。 自力で理解できなければ新しいスレッドを立てさせていただくと思いますので、またお力添えをしていただけると助かります。
簡単に説明すると、
戻り値はvoid、つまり戻り値がなくて、
引数は一つで第一引数の型はint型の値を取るといった感じでしょうか。
[hr][修正]0x01==>0x04
[修正]
みけCATさん>>そうですね、二重でミスりましたwww
指摘ありがとうございます。
最後に編集したユーザー bitter_fox on 2011年1月26日(水) 22:02 [ 編集 2 回目 ]

アバター
みけCAT
記事: 6294
登録日時: 9年前
住所: 千葉県
連絡を取る:

Re: C++ クラス(というか関数)の初歩なのですが・・・

#14

投稿記事 by みけCAT » 9年前

bitter_fox さんが書きました:また、0x32としたのは4バイトが32ビットになることからかと思いますが、メモリのアドレスは、一ビット単位ではなく、一バイト単位ですので、
0x00~0x01になります。
0x00~0x03ではないのですか?
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
みけCAT
記事: 6294
登録日時: 9年前
住所: 千葉県
連絡を取る:

Re: C++ クラス(というか関数)の初歩なのですが・・・

#15

投稿記事 by みけCAT » 9年前

[0x00][0x01][0x02][0x03][0x04]
5バイトある気がしますが...
表現方法の違いですか?
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
h2so5
副管理人
記事: 2212
登録日時: 9年前
住所: 東京
連絡を取る:

Re: C++ クラス(というか関数)の初歩なのですが・・・

#16

投稿記事 by h2so5 » 9年前

ベル さんが書きました: 関数というものは自販機のようなもの。 100円を入れるとなんか知らんけどジュースが出てくる。

これは”猫でもわかる~”の書籍で納得しました。 だからこそSetAのような返り値を持たない関数に関してはちょと腑に落ちないのです。 100円入れたけどジュースが出てこないってことではないのか? と思ってしまいます。
いわゆる「数学の関数」はベルさんの仰る通り、(たぶん)必ず帰ってくる数値があります。

ただしプログラミングの関数(サブルーチン)は、複数の処理を1つにまとめたものなので、
必ず返り値があるわけではありません。

ただしSetAのような関数でも、処理が成功したかどうかを返り値で返すものもあります。

これも参考になるかもしれません
http://ja.wikipedia.org/wiki/%E3%82%B5% ... 1%E3%83%B3

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 9年前
住所: 東海地方
連絡を取る:

Re: C++ クラス(というか関数)の初歩なのですが・・・

#17

投稿記事 by softya(ソフト屋) » 9年前

例えばSetとGetを同時にやって意味があるのか?
って実際に使ってみてください。

コード:

// CTest.h
class CTest { //CTestというクラスを定義
protected:
	int a;
public:
	int SetGetA( int _a );
};

//	CTest.cpp

#include "CTest.h"
void CTest::SetGetA( int _a )
{
	a = _a;
	return a;
}
すごく使えませんから。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

maru
記事: 150
登録日時: 9年前

Re: C++ クラス(というか関数)の初歩なのですが・・・

#18

投稿記事 by maru » 9年前

softya(ソフト屋) さんが書きました:
ベル さんが書きました: int a;
int SetA(100);
printf(%d,SetA);
とあんまり変わらないじゃん と思ってしまいます(これは私がクラスという概念をよくわかってないのが悪いのですが・・・)
それ、むちゃくちゃ文法的に出鱈目ですよ。
混乱させるようで申し訳ありませんが、このソースは文法的にも正しく、問題なく実行でき、さらに(間違った解釈でしょうが、多分ベルさんが意図しているように)正しく100が出力されます。
C++では
型 変数名(初期値);
の書式でオブジェクトの初期化宣言が可能です。初期値の型は変数の型と一致している必要はなく、その型に変換できるものであれば何でも構いません。
つまり、この
int SetA(100);
はint型の変数SetAを宣言して100で初期化しています。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 9年前
住所: 東海地方
連絡を取る:

Re: C++ クラス(というか関数)の初歩なのですが・・・

#19

投稿記事 by softya(ソフト屋) » 9年前

ポン!
そうでした!
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

maru
記事: 150
登録日時: 9年前

Re: C++ クラス(というか関数)の初歩なのですが・・・

#20

投稿記事 by maru » 9年前

あと、 関数名や変数名などの識別子は _ で開始しないようにしましょう。
int _a; /* 推奨されない */
こんな癖があるようなら、早く治しましょう。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 9年前
住所: 東海地方
連絡を取る:

Re: C++ クラス(というか関数)の初歩なのですが・・・

#21

投稿記事 by softya(ソフト屋) » 9年前

maru さんが書きました:あと、 関数名や変数名などの識別子は _ で開始しないようにしましょう。
int _a; /* 推奨されない */
こんな癖があるようなら、早く治しましょう。
それは、最初に書いてある「某”ゲームプログラミング応援サイト”」が犯人だと思うわけですが、_aはたしかにやめたほうが良いですね。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

ベル

Re: C++ クラス(というか関数)の初歩なのですが・・・

#22

投稿記事 by ベル » 9年前

おおお ちょっと勉強している間に大量のレスが! ありがとうございます><

bitter_fox様>>
4バイトが32ビットになることからかと思いますが、メモリのアドレスは、一ビット単位ではなく、一バイト単位

なるほど! ここでも理解不足でした>< ご指摘ありがとうございました!

ベル

Re: C++ クラス(というか関数)の初歩なのですが・・・

#23

投稿記事 by ベル » 9年前

みけCAT様>>
えっと 私が言うのもなんか変な感じですがいろいろ訂正ありがとうございます(?)

ベル

Re: C++ クラス(というか関数)の初歩なのですが・・・

#24

投稿記事 by ベル » 9年前

h2so5様>>
>>ただしプログラミングの関数(サブルーチン)は、複数の処理を1つにまとめたものなので、
必ず返り値があるわけではありません。

なるほど! 数学的に考えていたから混乱してしまったのですね! 処理だけ済んで用が終わればポイ捨て可!なわけですね やっと頭の中が整理できました

>>ただしSetAのような関数でも、処理が成功したかどうかを返り値で返すものもあります。

おおお また難しそうな・・・ またその局面に当たったら勉強いたします

ベル

Re: C++ クラス(というか関数)の初歩なのですが・・・

#25

投稿記事 by ベル » 9年前

softya(ソフト屋) 様>>

わざわざソースありがとうございます!

実際に動かしてみましたけどエラーがいくつかでますね・・・
「オーバーロード関数は、'int CTest::SetGetA(int)' と戻り値の型のみが異なります。」

なぜエラーが出るのかはまた明日ゆっくり勉強がてら考えて見ます

ベル

Re: C++ クラス(というか関数)の初歩なのですが・・・

#26

投稿記事 by ベル » 9年前

maru様>>
softya(ソフト屋)様>>

おお いつの間にか二人で会話が進んでらっしゃるw

確かにあのプログラムでも動きそうですがSetA関数のつもりで書いたのが変数になっちゃってますよねw

私が書きたかったのは

コード:

int a;        //aという変数を宣言
int SetA();  //SetA関数のプロトタイプ宣言

int SetA (int) //SetAの実態
{
a = 100;     //ただaという変数に100を代入しただけ
return a;
}

int main(void) //エントリポイント作成
{
(printf,SetA); //SetAの中身を出力
とこういうようなことが書きたかったわけですw ちょっと今も参考書無しで急いで書きましたので細かいミスとかあるかも知れませんがイメージは伝わりますでしょうか?

ちなみに_aという書き方ですがsoftya(ソフト屋)様がおっしゃってくださってるとおり某サイトからのコピペなのが原因です。

でもアンダーバーを使うのはよくないということを再認識いたしました。 どうもありがとうございました!

アバター
DVDM
記事: 38
登録日時: 9年前
住所: 大阪
連絡を取る:

Re: C++ クラス(というか関数)の初歩なのですが・・・

#27

投稿記事 by DVDM » 9年前

>>ベルさん
例えば 1+1は? とベルさんに尋ねたとします。
そして、ベルさんは 2 と答えました。

ここで「ベルさんという関数」に与えられたのが 「1」 と 「1」 の二つの引数です。
この関数の中で 1 + 1 を計算し、答えた 「2」と言うのが戻り値(return)になってます。

この 1 や 2 は整数なのか、小数も扱うのか、はたまた違う物なのか
それを認識させるために int 等の型を使います。
なので、この例で行くと

コード:

// 与えられた二つの値を足し算して返す(int 型のため整数のみの足し算)
int Bell(int a, int b)
{
	return a + b;
}
と、こんな感じになると思います。
なので、 printf("%d", Bell(1, 1)); と書くと、1+1 の結果を答えてくれたので printf で出力されるという事です。
つまり、答えてくれない(戻り値がない)と何を出力したらいいのか解らない訳です。
それが printf に SetA を使ったらエラーが出る理由です。(SetA は値をセットするだけで、戻り値はありません)


SetA では、「ベルさんコレをあの方に渡してきて下さい」という状態です。

渡しているもの(コレ)が引数で、あの方が メンバ変数 a になってます。
ちゃんと渡せたらベルさんはどうしますか?

渡せばそれで仕事は終わりです。
渡せたから報告はしなくてもいい、そんな状態なので戻り値は書かなくても大丈夫です。
もし、渡せたかどうか報告してほしい、そんな時に戻り値が一役買ってくれます。
それが、

> ただしSetAのような関数でも、処理が成功したかどうかを返り値で返すものもあります。

という一例になるのではないかなと思いました。


GetA ですが、
今度は「ベルさんあの方から荷物を取ってきて下さい」という状態です。
その荷物がどんなもの(型)なのか知る必要があります。

例えば、鉛筆取ってきて欲しいのに、消しゴム取ってこられたら
いや違うんですけど・・・ってなると思います。

それが、

> 「オーバーロード関数は、'int CTest::SetGetA(int)' と戻り値の型のみが異なります。」

このエラーの意味です。
つまり戻り値の型が宣言と定義で違うという事になります。


最後になりますが、softyaさんが仰っている

> SetとGetを同時にやって意味があるのか?

についてですが、「ベルさんコレをあの方に渡して、また返しに来て下さい」っていう状態です。
渡したものを返されるのですから、その処理に一体何の意味があるのでしょうか。
それだったら最初から渡す必要はなく、直接使えばいいと思います。


長々と書きましたが、難しく考えている感じがしたので自分なりにまとめてみた感じでした。
C++ ややこしいですが、頑張って下さい。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 9年前
住所: 東海地方
連絡を取る:

Re: C++ クラス(というか関数)の初歩なのですが・・・

#28

投稿記事 by softya(ソフト屋) » 9年前

超凡ミス・・・

コード:

// CTest.h
class CTest { //CTestというクラスを定義
protected:
    int a;
public:
    int SetGetA( int _a );
};
 
//  CTest.cpp
 
#include "CTest.h"
int CTest::SetGetA( int _a )
{
    a = _a;
    return a;
}

//	main.cpp
#include <stdio.h>
#include <conio.h>
#include "CTest.h"

int main( void )
{
	CTest ct;
	printf( "A=%d\n",ct.SetGetA(100) );	//setした値が戻ってくるだけ。
	getch();
	return 0;
}
改訂版です。

[追記]
ちなみに、名前として禁止されているのは
* グローバル スコープを持ち、_ で始まる名前
* _ で始まり、その次が大文字の名前
* __ を含む名前
です。
なので厳密には引数の_aはギリOK。だけで癖になるので間違えるからやめたほうが良いと思います。
代わりにa_やa_bなどはOK!
_aは古いC言語からC++に入った人が陥りやすい罠です(C90規格以前では明確には禁止ではない)
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

ベル

Re: C++ クラス(というか関数)の初歩なのですが・・・

#29

投稿記事 by ベル » 9年前

DVDM様>>

おおおおおお 非常にわかりやすい説明ありがとうございました! こういう噛み砕いた説明ってホントないんですよね・・・

確かにC++は難しいと思いますけど、概念がつかめてきただけでも割とマシになりましたよー

よく参考書には

「この関数は戻り値を返す」

とかあっさり書いてますけど、ド素人からすると

「返すって誰に?」

って感じでしたね。 まぁ今では呼び出し元(メインルーチン)に処理結果を渡すんだなぁぐらいにとりあえずは読めるようになりましたけど・・・


c言語って難しいからプロはあまりお勧めしないって聞きますけど実際どうなんでしょうね?

ベル

Re: C++ クラス(というか関数)の初歩なのですが・・・

#30

投稿記事 by ベル » 9年前

softya(ソフト屋)様>>
あれ? 改訂版でもエラー出ちゃいますw

リンクができないようで・・・
「error LNK2019: 未解決の外部シンボル _WinMain@16 が関数 ___tmainCRTStartup で参照されました。」

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 9年前
住所: 東海地方
連絡を取る:

Re: C++ クラス(というか関数)の初歩なのですが・・・

#31

投稿記事 by softya(ソフト屋) » 9年前

ベル さんが書きました:softya(ソフト屋)様>>
あれ? 改訂版でもエラー出ちゃいますw

リンクができないようで・・・
「error LNK2019: 未解決の外部シンボル _WinMain@16 が関数 ___tmainCRTStartup で参照されました。」
それは新規作成時のプロジェクトが違います。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

アバター
みけCAT
記事: 6294
登録日時: 9年前
住所: 千葉県
連絡を取る:

Re: C++ クラス(というか関数)の初歩なのですが・・・

#32

投稿記事 by みけCAT » 9年前

ところで、なぜコードタグがActionScriptなのでしょうか?
C++のコードなら最初を

コード:

としてください。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

ベル

Re: C++ クラス(というか関数)の初歩なのですが・・・

#33

投稿記事 by ベル » 9年前

softya(ソフト屋)様>>

プロジェクトですか・・・ 文法的なエラーではないということですね ありがとうございました!

ベル

Re: C++ クラス(というか関数)の初歩なのですが・・・

#34

投稿記事 by ベル » 9年前

みけCAT様>>

あ! 失礼しました。 意図はございません。 今後気をつけます

閉鎖

“C言語何でも質問掲示板” へ戻る