C言語何でも質問掲示板


アンケートにご協力下さい → >> アンケートフォーム <<

規約と使い方

 
   C++ 象徴クラスの活用 ....   
     ・[17333] たいちう 
     ・[17335] tkmakwins15 
     ・[17336] tkmakwins15 
     ・[17361] 鷹見 
     ・[17364] たいちう 
     ・[17367] 鷹見 
   フラグの誤立?   
     ・[17358] 管理人 
     ・[17365] 水孤 
   atan2エラーについて   
     ・[17323] Justy 
     ・[17331] box 
     ・[17354] ぴっぴ 
   入門編12、13につ ....   
     ・[17350] manako 
     ・[17352] 管理人 
     ・[17353] カッパ 
   C言語について   
     ・[17258] バグ 
     ・[17259] やそ 
     ・[17265] ABC 
     ・[17266] ABC 
     ・[17267] やそ 
     ・[17268] バグ 
     ・[17273] ABC 
     ・[17287] ABC 
     ・[17288] toyo 
     ・[17291] やそ 
     ・[17294] 管理人 
     ・[17319] ABC 
     ・[17320] tkmakwins15 
     ・[17342] ABC 
   ぐねぐねっとした動き ....   
     ・[17195] 柏 
     ・[17198] 管理人 
     ・[17199] 管理人 
     ・[17200] 管理人 
     ・[17207] 柏 
     ・[17208] 管理人 
     ・[17210] 管理人 
     ・[17211] 管理人 
     ・[17237] 柏 
     ・[17248] 管理人 
     ・[17325] 柏 
   質問   
     ・[17284] バグ 
     ・[17324] nemui 
   不思議な結果?   
     ・[17309] たいちう 
     ・[17310] たかぎ 
   Vistaでマウス操作   
     ・[17292] . 
     ・[17293] 管理人 
     ・[17300] hituzi 
   これは何故?   
     ・[17275] ベリ工 
     ・[17276] YuO 
     ・[17277] toyo 
   ゲームプログラミング ....   
     ・[17226] やそ 
     ・[17227] バグ 
     ・[17228] manako 
     ・[17232] やそ 
     ・[17233] manako 
     ・[17235] manako 
     ・[17236] Mist 
     ・[17239] manako 
     ・[17253] やそ 
     ・[17261] フリオ 
     ・[17263] manako 
     ・[17269] manako 
     ・[17271] やそ 
     ・[17272] manako 
   C++.構造体とクラスで ....   
     ・[17249] バグ 
     ・[17250] たかぎ 
     ・[17255] ランド 
   C言語の入門書の次に読 ....   
     ・[17206] kazuoni 
     ・[17213] バグ 
     ・[17217] Haru 
     ・[17218] やそ 
     ・[17221] マキガミ 
     ・[17251] やそ 
   弾とFPS   
   無題   
     ・[17243] Justy 
   引数について   
     ・[17223] 管理人 
   おききしたいのですが   
     ・[17203] box 
     ・[17212] toyo 
     ・[17214] やそ 
     ・[17215] uesama 
     ・[17216] 組木紙織 
   自動販売機   
     ・[17174] バグ 
     ・[17175] PEY 
     ・[17178] バグ 
     ・[17183] Haru 
     ・[17184] Haru 
     ・[17185] Haru 
     ・[17186] Haru 
     ・[17187] バグ 
     ・[17188] Mist 
     ・[17189] やそ 
     ・[17190] バグ 
     ・[17204] PEY 
   HPについてのご連絡   
     ・[17177] tkmakwins15 
     ・[17197] 管理人 
   scanfとgetcharについ ....   
     ・[17192] \n 
     ・[17193] toyo 
   VC++2005の無料版につ ....   
     ・[17180] バグ 
     ・[17181] Mist 
     ・[17182] tokumei 
   STGのスクリプト   
     ・[17092] バグ 
     ・[17096] Arma 
     ・[17098] tkmakwins15 
     ・[17104] へろり 
     ・[17113] Arma 
     ・[17130] Arma 
     ・[17134] 管理人 
     ・[17135] 管理人 
     ・[17173] Arma 
   電話帳のプログラム   
     ・[17163] tkmakwins15 
     ・[17164] TKOZ 
     ・[17166] TKOZ 
     ・[17168] tkmakwins15 
   再帰について   
     ・[17158] たかぎ 
     ・[17167] やそ 
   PLAYSOUND関 ....   
     ・[17154] 管理人 
     ・[17155] Mist 
     ・[17156] JEX 
     ・[17160] バグ 
     ・[17165] ibis 
   素数の和に関する質問   
     ・[17094] toyo 
     ・[17099] toyo 
     ・[17159] ぬっち 
   平均ベクトルの計算   
     ・[17151] kazuoni 
     ・[17153] GunCougar 
   敵のショット音が永遠 ....   
     ・[17032] 通りすがり 
     ・[17067] 南十字@ 
     ・[17102] 管理人 
     ・[17128] 南十字@ 
     ・[17132] 管理人 
     ・[17148] 南十字@ 
     ・[17149] 管理人 
   2次配列の最大要素数を ....   
     ・[17039] しっぽ 
     ・[17040] へろり 
     ・[17044] toyo 
     ・[17045] へろり 
     ・[17046] へろり 
     ・[17054] たかぎ 
     ・[17060] dolphin 
     ・[17062] たかぎ 
     ・[17144] dolphin 
     ・[17147] たかぎ 
   C言語とインラインアセ ....   
     ・[17026] すく 
     ・[17027] toyo 
     ・[17028] すく 
     ・[17146] LIL 
   whileとdo   
     ・[17119] ibis 
     ・[17121] box 
     ・[17126] DIL 
     ・[17142] ibis 
     ・[17143] 管理人 
     ・[17145] DIL 
   無題   
     ・[17110] kazuoni 
     ・[17114] 水銀 
     ・[17120] 管理人 
     ・[17140] 水銀 
     ・[17141] 管理人 
   DLL読み込みについて   
     ・[17084] みらの 
     ・[17097] ま〜く 
     ・[17107] Mist 
     ・[17139] みらの 
   おねがいします。   
     ・[17133] 管理人 
     ・[17138] たかぎ 
   2D見下ろし型アクショ ....   
     ・[17124] てつ 
     ・[17136] 管理人 
     ・[17137] てつ 
   ゲーム終了時の制御に ....   
     ・[17118] 管理人 
     ・[17131] 超初心者 
   ウインドウの枠   
     ・[17123] Lunar 
     ・[17125] Justy 
     ・[17127] Lunar 
   ミニゲーム   
     ・[16649] すく 
     ・[16650] 管理人 
     ・[16651] kazuoni 
     ・[16652] 管理人 
     ・[16653] 管理人 
     ・[16654] バグ 
     ・[16655] 管理人 
     ・[16656] kazuoni 
     ・[16657] 管理人 
     ・[16659] バグ 
     ・[16661] バグ 
     ・[16663] やそ 
     ・[16664] やそ 
     ・[16665] バグ 
     ・[16675] kazuoni 
     ・[16695] tkmakwins15 
     ・[16698] 管理人 
     ・[16754] テルル 
     ・[16792] バグ 
     ・[16824] 管理人 
     ・[16835] YuO 
     ・[16838] バグ 
     ・[16944] yos 
     ・[17015] バグ 
     ・[17033] lbfuvab 
     ・[17041] 管理人 
     ・[17052] バグ 
     ・[17053] バグ 
     ・[17066] 管理人 
     ・[17068] バグ 
     ・[17069] バグ 
     ・[17070] 管理人 
     ・[17111] kazuoni 
     ・[17112] バグ 
   画像が・・・   
     ・[17108] toyo 
   プログラミングの宿題 ....   
     ・[17073] Mist 
     ・[17074] たかぎ 
     ・[17075] バグ 
     ・[17080] 管理人 
     ・[17082] やそ 
     ・[17086] しっぽ 
     ・[17091] KEV 
     ・[17100] フリオ 
     ・[17101] フリオ 
     ・[17105] toyo 
     ・[17106] KEV 
   無題   
     ・[17061] TKOZ 
     ・[17064] 通りのてっちゃん 
     ・[17065] 管理人 
     ・[17071] TT414 
     ・[17081] mik 
     ・[17083] やそ 
     ・[17095] tkmakwins15 
   無題   
     ・[17088] バグ 
     ・[17093] バグ 
   標準入力は2回できない ....   
     ・[16789] tkmakwins15 
     ・[16840] ゆーじ 
     ・[16842] ibis 
     ・[16843] バグ 
     ・[16848] lbfuvab 
     ・[16851] ゆーじ 
     ・[16859] lbfuvab 
     ・[16860] Hermit 
     ・[16866] ibis 
     ・[16879] lbfuvab 
     ・[17085] ゆーじ 
   分かりません   
     ・[17077] 通り 
     ・[17078] mik 
   n個の数値の最大値と ....   
     ・[17058] やまさん 
     ・[17059] TKOZ 
     ・[17063] ディオ 
   ファイル読み込み書き ....   
     ・[17035] box 
     ・[17055] バグ 
   ポインタ   
     ・[17043] へろり 
     ・[17047] とーる 
     ・[17049] Mist 
     ・[17050] toyo 
     ・[17051] とーる 
   コンパイルエラーが出 ....   
     ・[16957] ibis 
     ・[16959] box 
     ・[16963] 超々初心者 
     ・[16964] box 
     ・[16965] 超々初心者 
     ・[16966] box 
     ・[16969] 超々初心者 
     ・[17038] しっぽ 
     ・[17048] 超々初心者 
   ぷよぷよ等パズルゲー ....   
     ・[17017] 管理人 
     ・[17022] バグ 
     ・[17036] Lunar 
   けせない・・・   
     ・[17030]  
     ・[17031] あなざぁ 
   ポインタの課題   
     ・[16990] バグ 
     ・[16991] net 
     ・[16992] net 
     ・[16994] へろり 
     ・[16995] バグ 
     ・[16996] バグ 
     ・[16997] KEV 
     ・[16998] net 
     ・[16999] net 
     ・[17000] へろり 
     ・[17002] へろり 
     ・[17003] KEV 
     ・[17011] KEV 
     ・[17012] net 
     ・[17013] net 
     ・[17016] へろり 
     ・[17018] net 
     ・[17019] KEV 
     ・[17020] net 
     ・[17021] KEV 
     ・[17023] net 
     ・[17024] KEV 

Name: 鷹見  ..ぴよぴよ(955ポイント)   Date: 2008/06/14(土) 06:04   No:17328       
Title: C++ 象徴クラスの活用法    
おはようございます。
C++をひと通り勉強しましたのですが、象徴クラスの利便性がいまいち解りません。
又 
私はクラスのオブジェクトをグローバルに置くことがほとんどです。
グローバルにはあまり置かないほうがよいでしょうか?

なるべく実用的なプログラムの書き方をしたいと思っています。
なにか良い参考例やアドバイスがありましたらお願いします。


123ポイント を手に入れた。


Name: たいちう  ..ぴよぴよ(959ポイント)   Date: 2008/06/14(土) 14:37   No:17333     
Title: Re:C++ 象徴クラスの活用法    
象徴クラス?抽象クラスですよね。

> なるべく実用的なプログラムの書き方をしたいと思っています。
> なにか良い参考例やアドバイスがありましたらお願いします。

まず、どうやって書くかよりも何を書くかです。
入門書を一冊位終えた頃には、これを考えなくてはなりません。
オブジェクト指向を身に付けてから、書きたいプログラムを書くのではなく、
書きたいプログラムを書く過程で、オブジェクト指向を身に付けましょう。
何のプログラムを書きたいですか?書く必要があるのですか?

オブジェクト指向の良い例とされているのが、「デザインパターン」として
まとまっています。書籍もサイトも色々ありますので、自分に合ったものを
探してみてはいかがでしょうか。

クラスを使わずに、変数も全てグローバルでも、プログラムを作ることはできます。
作りたいプログラムを自由に完成させてから、「デザインパターン」等を
当てはめて改良することで、色々な書き方のメリット・ディメリット、つまり、
変更の容易さや可読性、冗長性、危険性などが理解できると思いますよ。
このような改良は「リファクタリング」といいます。
この方法についても調べてみると良いでしょう。


252ポイント を手に入れた。

Name: tkmakwins15 [URL]  ..比類無きプログラマー(75,102ポイント)   Date: 2008/06/14(土) 14:59   No:17335     
Title: Re:C++ 象徴クラスの活用法    
>象徴クラスの利便性がいまいち解りません。

抽象クラスの基本的な使い方は、複数のオブジェクトに共通の操作方法を持たせる事です。
例えば、軽自動車と普通自動車の二つのクラスを作るとします。この二つは規格や最高速度、加速性能などは違うので、同じクラスにすると言うのはおかしな話です。
ところが、どちらにしろ自動車である事に間違いはないのですから、同じ「走る」ことや、「止まる」こと、「曲がる」ことが、同じアクセルやブレーキ、ハンドルでできるはずです。そこで、「自動車」の共通の操作方法を持たせるのが自然ですよね。それが、抽象基本クラスということになります。以下参考。

#include<iostream>
#include<string>
#include<sstream>
#include<exception>
#include<new>
#include<cstdlib>
using namespace std;

class iCar{
protected:
string mkind;
int mforward;
public:
//進行方向を表す定数
static const int North;
static const int East;
static const int South;
static const int West;

//コンストラクタ
iCar(const string& kind){
mkind=kind;
mforward=North;//初期進行方向は北方面
}
//純粋仮想関数
virtual void Run()=0; //進行方向へ加速
virtual void Stop()=0; //停止
virtual void TurnRight()=0; //右に曲がる
virtual void TurnLeft()=0; //左に曲がる
virtual bool isStop()=0; //停止しているかのフラグを返す。
virtual string StateString()=0; //状況を表す文字列を返す。

//出力関数
friend ostream& operator<<(ostream&stream,iCar&obj);
};

ostream& operator<<(ostream&stream,iCar&obj){
char *fwstr[]={"北","東","南","西"};
stream<<"自動車の種類:"<<obj.mkind<<endl;
stream<<"進行方向:"<<fwstr[obj.mforward]<<endl;
stream<<obj.StateString();
return stream;
}

const int iCar::North=0;
const int iCar::East=1;
const int iCar::South=2;
const int iCar::West=3;

class NormalCar:public iCar{
int speed;
public:
NormalCar():iCar("普通自動車"){
speed=0;
}

void Run(){
if(speed<40)speed+=10;
else if(speed<90)speed+=7;
else if(speed<175)speed+=3;
else if(speed<199)speed+=2;
else if(speed<200)speed=200;
}
void Stop(){
speed=0;
}
void TurnRight(){
mforward=(mforward+1)%4;
speed/=12;
}
void TurnLeft(){
mforward=(((unsigned)mforward)-1U)&3;
speed/=10;
}
bool isStop(){
return speed==0;
}
string StateString(){
ostringstream state;
state<<"速度:"<<speed<<"km/h";
return state.str();
}
};

class LightCar:public iCar{
int speed;
public:
LightCar():iCar("軽自動車"){
speed=0;
}

void Run(){
if(speed<30)speed+=8;
else if(speed<90)speed+=5;
else if(speed<145)speed+=1;
}
void Stop(){
speed=0;
}
void TurnRight(){
mforward=(mforward+1)%4;
speed/=8;
}
void TurnLeft(){
mforward=(((unsigned)mforward)-1U)&3;
speed/=6;
}
bool isStop(){
return speed==0;
}
string StateString(){
ostringstream state;
state<<"速度:"<<speed<<"km/h";
state<<"最高速度:"<<145<<"km";
return state.str();
}
};

int main()
{
iCar *car;
int select;
cout<<"どちらの車を選びますか?"<<endl;
cout<<"1:普通乗用車 2:軽自動車"<<endl;
cin>>select;
try{
if(select==1){
car=new NormalCar;
}else if(select==2){
car=new LightCar;
}else{
cout<<"正しい選択をしてください"<<endl;
exit(0);
}
}catch(bad_alloc&){
cerr<<"メモリの確保に失敗しました"<<endl;
abort();
}

cin.get();

bool isloop=true;
while(isloop){
cout<<"車を走らせますか?(Y/N):";
if(cin.get()=='Y')car->Run();
cin.get();
if(car->isStop()){
cout<<"車は止まっています。運転を続けますか?(Y/N):";
if(cin.get()=='N')isloop=false;
cin.get();
}
int happening=rand();
if(happening==0){
cout<<"子供が飛び出してきました。停止します。"<<endl;
car->Stop();
}else if(happening%25==0){
int select;
cout<<"交差点です。どうしますか?"<<endl;
cout<<"1:直進 2:右に曲がる 3:左に曲がる"<<endl;
cin>>select;
cin.get();
if(select==2)car->TurnRight();
else if(select==3)car->TurnLeft();
}
cout<<*car<<endl;;
}

return 0;
}


たぶんこんな感じです。


2,040ポイント を落としてしまった。

Name: tkmakwins15 [URL]  ..比類無きプログラマー(76,604ポイント)   Date: 2008/06/14(土) 15:13   No:17336     
Title: Re:C++ 象徴クラスの活用法    
あっ、ミスってました。これが正しいコードです。

#include<iostream>
#include<string>
#include<sstream>
#include<exception>
#include<new>
#include<cstdlib>
using namespace std;

class iCar{
protected:
string mkind;
int mforward;
public:
//進行方向を表す定数
static const int North;
static const int East;
static const int South;
static const int West;

//コンストラクタ
iCar(const string& kind){
mkind=kind;
mforward=North;//初期進行方向は北方面
}
//純粋仮想関数
virtual void Run()=0; //進行方向へ加速
virtual void Stop()=0; //停止
virtual void TurnRight()=0; //右に曲がる
virtual void TurnLeft()=0; //左に曲がる
virtual bool isStop()=0; //停止しているかのフラグを返す。
virtual string StateString()=0; //状況を表す文字列を返す。

//出力関数
friend ostream& operator<<(ostream&stream,iCar&obj);
};

ostream& operator<<(ostream&stream,iCar&obj){
char *fwstr[]={"北","東","南","西"};
stream<<"自動車の種類:"<<obj.mkind<<endl;
stream<<"進行方向:"<<fwstr[obj.mforward]<<endl;
stream<<obj.StateString();
return stream;
}

const int iCar::North=0;
const int iCar::East=1;
const int iCar::South=2;
const int iCar::West=3;

class NormalCar:public iCar{
int speed;
public:
NormalCar():iCar("普通自動車"){
speed=0;
}

void Run(){
if(speed<40)speed+=10;
else if(speed<90)speed+=7;
else if(speed<175)speed+=3;
else if(speed<199)speed+=2;
else if(speed<200)speed=200;
}
void Stop(){
speed=0;
}
void TurnRight(){
mforward=(mforward+1)%4;
speed/=12;
}
void TurnLeft(){
mforward=(((unsigned)mforward)-1U)&3;
speed/=10;
}
bool isStop(){
return speed==0;
}
string StateString(){
ostringstream state;
state<<"速度:"<<speed<<"km/h";
return state.str();
}
};

class LightCar:public iCar{
int speed;
public:
LightCar():iCar("軽自動車"){
speed=0;
}

void Run(){
if(speed<30)speed+=8;
else if(speed<90)speed+=5;
else if(speed<145)speed+=1;
}
void Stop(){
speed=0;
}
void TurnRight(){
mforward=(mforward+1)%4;
speed/=8;
}
void TurnLeft(){
mforward=(((unsigned)mforward)-1U)&3;
speed/=6;
}
bool isStop(){
return speed==0;
}
string StateString(){
ostringstream state;
state<<"速度:"<<speed<<"km/h";
state<<"最高速度:"<<145<<"km";
return state.str();
}
};

int main()
{
iCar *car;
int select;
cout<<"どちらの車を選びますか?"<<endl;
cout<<"1:普通乗用車 2:軽自動車"<<endl;
cin>>select;
try{
if(select==1){
car=new NormalCar;
}else if(select==2){
car=new LightCar;
}else{
cout<<"正しい選択をしてください"<<endl;
exit(0);
}
}catch(bad_alloc&){
cerr<<"メモリの確保に失敗しました"<<endl;
abort();
}

cin.get();

bool isloop=true;
while(isloop){
cout<<"車を走らせますか?(Y/N):";
if(cin.get()=='Y')car->Run();
cin.get();
if(car->isStop()){
cout<<"車は止まっています。運転を続けますか?(Y/N):";
if(cin.get()=='N')isloop=false;
cin.get();
}
int happening=rand();
if(happening==0){
cout<<"子供が飛び出してきました。停止します。"<<endl;
car->Stop();
}else if(happening%25==0){
int select;
cout<<"交差点です。どうしますか?"<<endl;
cout<<"1:直進 2:右に曲がる 3:左に曲がる"<<endl;
cin>>select;
cin.get();
if(select==2)car->TurnRight();
else if(select==3)car->TurnLeft();
}
cout<<*car<<endl;;
}

delete car;

return 0;
}

解放忘れという初歩的なミスをしてしまうとは…


2倍のポイントを手に入れた! 1,502ポイント を手に入れた。

Name: 鷹見  ..かけだし(1,192ポイント)   Date: 2008/06/15(日) 05:05   No:17361     
Title: Re:C++ 抽象クラスの活用法    
(タイトル打ち間違えすみませんでした。)

お二人ともありがとうございます。
一度自由に作ってから、徐々に効率が良くなるように修正していくのもテですね。


抽象クラスはこの先、いくつの派生クラス作るかわからないとき抽象化しておき
派生クラスの数を増やしやすいことでしょうか?

抽象クラスのオブジェクトポインタを一つ作り、必要な物(上のコードではswitchの所)をそのポインタに入れることでプログラムのルート上今回は使わない(例 上コード、軽自動車 又は 普通自動車)物を作らず。
メモリの消費を抑えることになる。

と言うのが考えてみた結果になりました。


コードまで載せて頂き助かります やっぱりnewで確保したのはdeleteするのはぜったいですね。
私はまだあまり慣れていないので結構deleteし忘れます。今回のアドバイスを元にもう少し打ちながら考えてみます、ありがとうございました。