クラスについて質問です
class Product{
char name;
int price;
}
としたときnameとnameとどどちらがメンバなのでしょうか。
例えばこのクラスのオブジェクトproduct1に対してmain関数内で
char example='a';
product1.*name= example;
としたときに、変数example自体はproduct1のメンバなのでしょうか。それともexampleのポインタのみがメンバですか?
そしてこのように、「ポインタをクラスのメンバ」にするような書き方は一般にするものですか?
そもそもポインタは変数ではないのでメンバという言い方はしないのでしょうか?
質問が多くてすいません。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答7件
0
product1.*name= example;
は正しくは
*product1.name= example;
C,C++には便利な演算子がありまして、「ポインタ変数がクラスのメンバであり、その中身へとアクセスする場合」には、通常->演算子(アロー演算子)を使います。
exampleを代入する場合には下記のようになります。
product1->name = example;
投稿2015/02/24 06:26
総合スコア16
0
nameと*nameとどどちらがメンバなのでしょうか。
クラスのメンバ(変数)とは、その「変数名」のことを指します。この例ではname
がメンバ(変数)です。
としたときに、変数example自体はproduct1のメンバなのでしょうか。
それともexampleのポインタのみがメンバですか?
メンバ(変数)の前に、「クラス」と「インスタンス」の関係、「型」と「変数」の関係がごっちゃになっているようです。まずは簡単なint
型のprice
メンバ変数で考えてみてください。
class Product { /*省略*/ }; Product product1; int val = 100; product1.price = val;
- クラス
Product
型の変数product1
には、その値としてクラスProduct
から作り出したインスタンスが格納されています。 int
型の変数val
には、値100
が格納されています。procut1.price
は、変数product1
に格納されたProduct
型インスタンスの、int
型のメンバ変数price
を表します。product.price = val;
とすると、変数product1
に格納されたProduct
型インスタンスの、int
型のメンバ変数price
に、値100
がコピーされて代入されます。
// 質問文から転機したコード char example = 'a'; product1.*name = example;
なお、質問文にあるコードではコンパイル時エラーになります。下記のように*
を先頭に書く必要があります。(これでコンパイルは通るようになりますが、別の問題があるため実行時エラーになります。)
// 修正したコード char example = 'a'; *product1.name = example;
そしてこのように、「ポインタをクラスのメンバ」にするような書き方は一般にするものですか?
一般的です。
そもそもポインタは変数ではないのでメンバという言い方はしないのでしょうか?
ポインタは「型」です。「int
型の変数」と同じように、「ポインタ型の変数」という言い方をします。例えばint *p;
は、「int
型へのポインタ型(=int *
型)の変数p
」になります。先の例では、「クラスProduct
のメンバ変数price
は、char
型へのポインタ型(=char *
型)のメンバ変数」となります。
正しくは *product1.name= example; と書く必要があり、インスタンスを生成するときにnew、deleteで領域を確保しないとエラーがでてしまう
本質的な問題はproduct1.name
が有効なメモリを指していない、つまりポインタ型のメンバ変数name
を初期化していないことです。「インスタンスを生成するときにnew、deleteで領域を確保」は、初期化のための1つの手段です。(他の方法も考えられます)
*product1.name
はポインタ型変数が指す先を見に行く(参照はがし)操作ですが、product1.name
が有効なメモリ(変数)を指していない状態では、プログラムクラッシュなどの実行時エラーを引きおこしたり、全く無関係なメモリ(変数)に書き込んで値を破壊する不可解なバグの原因となります。
投稿2015/02/19 16:17
編集2015/02/20 06:40総合スコア6189
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
ベストアンサー
言語仕様として正しいかどうか自信はありませんが、回答してみます。
としたときnameと*nameとどどちらがメンバなのでしょうか。
name
がメンバー変数です。
char *name
はchar *
型の変数と捉えたほうが分かりやすいと思います。
例えばこのクラスのオブジェクトproduct1に対してmain関数内で
char example='a';
product1.*name= example;
としたときに、変数example自体はproduct1のメンバなのでしょうか。それともexampleのポインタのみがメンバですか?
メンバーというのは、クラスに所属している変数と関数のことですので、Product
クラスのメンバーはname
とprice
だけです。
そしてこのように、「ポインタをクラスのメンバ」にするような書き方は一般にするものですか?
一般的に良く使うと思います。と言っても、C++の場合はstring
やvector
のようにコンテナーの中にポインターを内包することが多いので、間接的に使うことが多いということになるのでしょうか。
ご質問の内容とは少しずれますが、もし文字列としてchar *
を使うのであれば、動的に文字列のメモリーを確保することになります。その場合は、メモリーの割り当てと解放を自前で行う必要があります。解放は、クラスのデストラクタ―で行います。
そもそもポインタは変数ではないのでメンバという言い方はしないのでしょうか?
char *name
は、「char
型のポインター」の変数です。
上で書いた通りで、これもメンバー変数です。
参考URL:
C/C++は永久に不滅です! - Part4 誰もがつまずくポインタを完璧理解:ITpro
(追記)
*product1.name= example;
の*
は、ポインターの(アドレスに格納されている先の)値にアクセスする(演算を行う)、という意味なので、*product1.name
がメンバーかどうか、という問いをすることは無いと思います。
C/C++の場合、明示的にメモリーの解放(C++の場合はdeleteで行う)をしないと、すぐにエラーにはならず、メモリーリークという状態となってしまうので、特に注意が必要です。
投稿2015/02/19 15:16
編集2015/02/20 05:41総合スコア9388
0
様々な方が意見していただいているので補足だけ。
そしてこのように、「ポインタをクラスのメンバ」にするような書き方は一般にするものですか?
一般的な理由をあげると、クラスのメンバ変数にしない場合、外部からアクセス可能になり様々なトラブルの原因となります。(ポインタのアドレスを変更した:newで動的確保した場合deleteできないなど)
ポインタを直接扱える状態にすることはC++の思想から好ましくありません。
複数人での開発を考えると、privateで保護することが望ましいでしょう。
インスタンスを生成するときにnew、deleteで領域を確保しないとエラーがでてしまう
newで動的確保する理由は
0. 値を代入できる領域の確保
0. 入ってくるデータ量が不定(バッファオーバーフロー対策)
0. 必要な分だけの領域を使用する(文字列など1文字から不定)
などが挙げられます。
投稿2015/02/26 13:28
総合スコア24
0
exampleをnameへ代入する場合、
- nameのメモリー領域を確保。
- exampleの内容(この場合、'a')をnameにコピー。
- nameを使わなくなったら、メモリーを開放(デストラクタなどで)。
の手順になります。
1.2.を行うことで、exampleの実体が無くなっても(exampleがローカル変数で、サブルーチンから抜けるなどでスコープから外れても)、Productのインスタンスがある限り、nameが値を保持しています。
投稿2015/02/24 13:29
退会済みユーザー
総合スコア0
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2015/02/24 13:42
退会済みユーザー
2015/02/24 14:18
2015/02/25 14:03
0
この場合のメンバ変数になるのは
「char型のポインタ型」の変数nameであり、その内容(char型の変数)*nameはメンバ変数ではない、と理解致しました。
「メンバ変数nameはcharポインタ型である。」
ここまではあっています。
「その内容(char型の変数)*nameはメンバ変数ではない」
上記についてですが、「*name」はchar型の変数ではありません。
「charポインタ型の変数nameの中身を参照する」という操作です。
ポインタの中身を参照するために変数の前につける""と、変数宣言時の""の部分で混乱してそうですね。
ちなみに、多くの教科書でポインタの宣言は「char name;」というような記載になっていますが、上記のような誤解を招きやすいので「char name;」と宣言することをお勧めします。
投稿2015/02/24 05:41
総合スコア16
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2015/02/24 13:38
2015/02/25 00:00
0
ポインタをクラスのメンバにすることはいたって普通に行う事です。そうでないとオブジェクト間の関連とか表現できませんから。
ちなみに、ポインタであるメンバにアクセスするときはアスタリスクは先頭に付けます。
lang
1char* example = "abc"; 2product1.name = example; 3char c = *product1.name;
あと、下記はproduct1.nameが指す領域が確保されていないので、実行時エラーになるはずです。。
lang
1char example = ’a’; 2*product1.name = example;
投稿2015/02/19 15:23
総合スコア209
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2015/02/24 13:39