今C++を学び始めたものなのですが、C++においてメンバ関数を定義する意味が分かりません。

ベストアンサー

1

1人がナイス!しています

ThanksImg質問者からのお礼コメント

回答ありがとうございます!例文を出していただいたおかげで大変分かりやすかったです!

お礼日時:3/5 18:27

その他の回答(5件)

0

まず、前提がおかしいです。 メンバ関数が必要かどうかではなく、『何のためのオブジェクト指向なのか』です。 オブジェクト指向(以降、OOP) の基本概念が理解できていないと話になりません。(そうしないとなぜメンバ関数ってのがあるのかさえわからない) -------------------------------------- OOPってのは、『データ(= メンバ変数) と処理(= メンバ関数) をひとまとめにしたオブジェクト』なるものを中心に見る発想法です。 C++を使っているのでしたら、C言語は使えますよね? C言語ありで説明します。 C言語( 以下 単に C という ) で『ファイルの書き込み』をイメージしてください。 FILEポインタを使って fopen関数とかでファイルを開いたり、書き込んだり、閉じたりしますよね。 FILE* fp = fopen( "ファイル名", "w" ); fprintf( fp, "書き込むデータ" ); fclose( fp ); と言う風に。 でもよく見ると、fp っていうデータを毎回渡していますね。 で、複数のファイルがある場合、 FILE* fp1 = fopen( "ファイル名", "w" ); FILE* fp2 = fopen( "ファイル名", "w" ); ... fprintf( fp1, "データ1" ); fprintf( fp2, "データ2" ); ... fclose( fp1 ); fclose( fp2 ); ... のように、fprintf関数とかに fp1やら fp2 やらを渡しています。 なんだか面倒ですね。 これをFILEポインタをメンバ変数として保持し、 メンバ関数として write系のメンバ関数を持つとしましょう。 class FileWriter{ ____public: ________// コンストラクタ ________FileWriter( const char* filepath ){ ____________fp = fopen( filepath, "w" ); ________} ________ ________// デストラクタ ________~FileWriter(){ ____________fclose( fp ); ________} ________ ________// メンバ関数 write ________int write( const char* data ){ ____________return fprintf( fp, data ); ________} ____private: _______FILE* fp; }; のように、 コンストラクタで fopenし、デストラクタでfclose し、 writeメンバ関数で fprintf関数を呼び出して書き込んでいるとします。 そうすると、 このクラスを使う側は、 FileWriter file( "ファイル名" ); file.write( "データ1" ); file.write( "データ2" ); のようにできる。 つまり、『オブジェクトにデータの処理や管理を任せる』のです。 言い換えると『オブジェクトだけが対象データと処理方法を知っている』状態です。 会社と営業部の人の関係に近いです。 会社は営業部の人に『わが社のこの商品を売りさばいてくれ』的な感じで任せます。 で、会社は基本、売り方までは指定しません。 余程、悪質で、違法性の高い売り方でない限り。 会社は『売りさばく事(= 概要)』と『その売り上げ(= 結果)』だけしか興味がありません。 で、『営業部の人それぞれ』が、『売る商品』と『売り方』を知っています。 それぞれの人が自分で管理や処理をします。 この状態です。 これをやるための発想がOOPです。 そして、クラスはこのオブジェクトなるものを作るためのものです。 コンパイラやインタプリタ( C++の場合はコンパイラ ) に、 『こういうデータ構造のやつがあるんで、よろしく~♪』って感じで教えてあげるだけです。 Cでも、『プロトタイプ宣言』ってありますよね。あれと一緒です。 そのクラスからオブジェクトなるものを生成して、オブジェクトに管理や処理を任せるのがOOPです。 だからクラスを組めばOOP……ではないです。 JavaScriptとかみたいに、クラスが無いOOP言語もあります。(最近のJavaScriptではクラスがあるようだが……) そして、そのオブジェクトが行う処理として定義されているのが『メンバ関数』です。 JavaやC#なら『メソッド(方法)』と呼ばれています。 だから、クラス外で定義する関数(ふつうの関数。いわゆるグローバル関数)とは目的が違うのです。 普通の関数は、C言語由来のもので、メンバ関数はOOPを表現するためのものです。

0

もし構造体だったらどうなるか?と考えてみるとよろし。 クラス内で定義すれば、当然「そのクラス専用の関数」となります。「そのクラス専用」なのですから、「他のクラス専用」とは区別されますし、そもそも特定のクラスには属さない一般の関数とも区別されます。 この「区別される」というのが重要です。それは「区別できる」ということでもあり、つまりは「区別できるのだから同じ名前の関数を定義できる」わけです。 クラスhoge1、クラスhoge2、クラスhoge3…とあったとして、それぞれに「archive」という名の関数を定義できるわけです。 これにより、使用する側にとっては「どのクラスでも同じ名前の関数で同じ操作ができる」というメリットが生まれます。 構造体hoge1、構造体hoge2、構造体hoge3…に対して同じことをしようとしたら、それぞれの構造体用に「お互いに被らない名前」を付けなければなりません。hoge1archiveとかhoge2archiveとかhoge3archiveとか、ね。 あとは、メンバ変数への直接アクセスを禁じて必ずメンバ関数を使用させることにより各メンバ間の整合性を維持する、なんてことにも使えます。 これが構造体なら、使う側に整合性を保つ義務を背負わせねばならなくなりますし、仮にそのための関数を用意するとなると(以下同文)。

0

クラスのメリットが有るだけの事です。クラスのメリットとはインスタンス化で1個のクラスから複数のインスタンスが作れるメリットが有るだけの事です。その中にメソッドが有る事が何のメリットが有るかははなはだ疑問ですが、専門家は有ると言っているようです。個人的にはプログラムが解読困難に成るだけの困った存在と思います。

2

>クラス内で関数を定義するとメリット そういう作法であると受け入れつつ思考停止してそのまま(カラテとかで言われるような)型に従うのが手っ取り早いです つまり、メリットを考える前に型を覚えます

2人がナイス!しています