• ベストアンサー

C++勉強中なんですが

クラス等を使ってソースを書く練習中なのですが、思ったように結果が出ません。 #include<iostream> #include<string> using namespace std; class Cats { private://クラス「Cats」の中でのみ使う文字列の入れ物変数「name」を作る string name; public://クラス「Cats」の外からでも引数で呼び出せば使える Cats(string x)//クラスCatsの関数Cats(コンストラクタ)を使いますよって宣言 { name=x;//8行目で作った文字列の入れ物に変数xを入れる } void naku()//voidの意味が正確には分からないけど、何も返さないって意味らしいので、何も返さないnakuって関数を作る { cout<<"にゃっふぅーん、ボク、"<<name<<"ってゆーの。よろしくネ!"<<endl;//関数nakuが呼び出されると文字列を表示する } }; int main()//全体のプログラム { string x;//まず文字列の入れ物になる変数xを作る cout<<"今日新たな家族になるにゃんこが産まれました。"<<endl; cout<<"名前を決めてあげましょう!"<<endl; Cats aisatsu(x);//クラスCatsのメンバーaisatsuを作る(中身は文字列の変数x) cin>> x;//変数xにキーボードで書いた文字列を入れる aisatsu.naku();//メンバー関数のaisatsuがグローバル関数(クラスの外からでも呼べるはずw)nakuを呼び出す } cin>>x;で入力した文字がnameに代入されてないのか、表示されません・・・。 もし分かる方いたら是非教えていただきたいです。 あと、コメントアウトしてる部分なんですが、ここもおかしい認識があればご指摘いただきたいです。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.3

#2です。 #2の私の回答への補足にnery1024さんが書いたとおりで、OKです。 あと、クラスを定義するとき、この場合は、1つのファイルにすべてを書いていますが、ヘッダーファイルという(*.h)別のファイル内に記述することが多いです。 なので、クラスのメンバ変数・関数の宣言だけをヘッダーに書き、 その関数の内容については、*.cpp内に書くことが多いのです。 そのとき、そのcppファイル内で、クラスを定義したヘッダーをincludeすればよいのです。 この場合ですと、 Cats.hに #ifdef __Cats_   //ヘッダを多重includeするときには必ず必要です #define __Cats_ //この行も class Cats{ private:    string name; public:    Cats();    Cats(string x);    void naku(); }; #endif //最後にこの行も必要です を書き、 Cats.cpp に #include <iostream> #include "Cats.h" using namespace std; Cats::Cats(){ } Cats::Cats(string x){ name=x;//8行目で作った文字列の入れ物に変数xを入れる } void Cats::naku(){    cout<<"にゃっふぅーん、ボク、"<<name<<"ってゆーの。よろしくネ!"<<endl; } を書き、main.cppにmain関数を書けばよいです。 #include<iostream> #include<string> #include "Cats.h" using namespace std; int main()//全体のプログラム {   string x;//まず文字列の入れ物になる変数xを作る   cout<<"今日新たな家族になるにゃんこが産まれました。"<<endl;   cout<<"名前を決めてあげましょう!"<<endl;   cin>> x;//変数xにキーボードで書いた文字列を入れる   Cats aisatsu(x);//クラスCatsのメンバーaisatsuを作る(中身は文字列の変数x)   aisatsu.naku();//メンバー関数のaisatsuがグローバル関数(クラスの外からでも呼べるはずw)nakuを呼び出す   return 0; // これを付け足してください }

nery1024
質問者

お礼

なるほど。 めちゃくちゃわかりやすいです。 ヘッダーファイルを出力するやり方とか、#ifdefとかはまだ覚えてないので、もう少し勉強が進んでからこの回答を参考にさせていただきますね。 return 0; は了解です。 ありがとうございました!

その他の回答 (3)

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.4

コンストラクタでメンバー name に値を設定するときには Cats(string x) : name(x) { } のように「初期化」をする方がよいです. デフォルトコンストラクタは不要なら定義しなくていいです. ちなみに「_+大文字」とか「__」とかで始まる識別子を使うのは危険かもしれない. おっととと, なんでクラス名が Cats と複数形なんだろう?

nery1024
質問者

お礼

>Cats(string x) >: name(x) >{ >} 回答ありがとうございます。 このソースを処理が終わったあとあたりに書くと初期化するって意味なんですかね? Catsと複数形にしたのは、勉強してて参考にしてるサイトに、クラスは色んなところに使いまわせるのが便利。みたいな説明を見たので、今回は使いまわさないだろうけど、使いまわすの前提で名付けました・・・。 使いまわすような事があると、恐らくは初期化したほうが良いとかになってくると勝手に予想させていただくとして、この質問回答はずっと残りそうなので、そのときがきたらTacosanの回答を参考にさせていただきます! あと、大文字から始まるのはやめたほうが良いんですね。 了解しました。

回答No.2

main関数内の、cin>>x; の部分がおかしいです。 Catsクラスの定義する前に入れてあげてください。 int main()//全体のプログラム {    string x;//まず文字列の入れ物になる変数xを作る    cout<<"今日新たな家族になるにゃんこが産まれました。"<<endl;    cout<<"名前を決めてあげましょう!"<<endl;    cin>> x;//変数xにキーボードで書いた文字列を入れる    Cats aisatsu(x);//クラスCatsのメンバーaisatsuを作る(中身は文字列の変数x)    aisatsu.naku();//メンバー関数のaisatsuがグローバル関数(クラスの外からでも呼べるはずw)nakuを呼び出す } でいいです。 あと、Cats aisatsu(x);はインスタンスの定義部分です。 Cats(string x);でコンストラクタを設定していますが、 しかし、普通、Cats();でデフォルトコンストラクタというのを定義しておかなければなりません。警告が出る可能性があります。 コンストラクタ定義部分の、コメントに「//8行目で作った文字列の入れ物に変数xを入れる」とありますが、このようにして関数を定義したいのであれば、コンストラクタで定義するべきではないと思います。 なぜなら、コンストラクタは、クラスの初期化のときに、どのような処理を行うかを決めるのがコンストラクタであるからです。 だから、Catsクラスのメンバ関数にsetString(string x)関数を定義して、データをCatsクラスに入れた方がよいのではないかと思います。 また、クラスの定義部分に、普通は関数を書かないです。 ですから、クラスの定義は、 class Cats{ private:    string name; public:    Cats();    Cats(string x);    void naku(); }; として、main()関数の前くらいに、 Cats::Cats(){ } Cats::Cats(string x){ name=x;//8行目で作った文字列の入れ物に変数xを入れる } void Cats::naku(){    cout<<"にゃっふぅーん、ボク、"<<name<<"ってゆーの。よろしくネ!"<<endl; } を書いておくべきだと、思います。 ここに書いたのは、あくまで、私個人のコーディング慣習ですから、このような書き方があるというように理解してほしいです。

nery1024
質問者

補足

とても興味深いのですが、理解しきれてません。 main関数の前にとの事ですが、ソースを書いてみますね。 #include<iostream> #include<string> using namespace std; class Cats{ private:    string name; public:    Cats();//ここで関数Catsを使うよって意味かな←    Cats(string x);//Catsの中身は文字列xだよ←    void naku();//なにも返さない関数nakuを使うよ }; ここまでで、←の部分は、まずからっぽの関数を作る事で、今の自分には分からないのですが、主にどういった時にそう記述したほうが良いのでしょうか? 続きは、main関数の前とあるのは、 Cats::Cats(){ } Cats::Cats(string x){ name=x; } void Cats::naku(){    cout<<"にゃっふぅーん、ボク、"<<name<<"ってゆーの。よろしくネ!"<<endl; } ここまで書いた後に、 int main(){ string x; ・ ・ ・ の様に記述すればいいのでしょうか?

  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.1

> Cats aisatsu(x);//クラスCatsのメンバーaisatsuを作る(中身は文字列の変数x) の時点でx(この時点で空文字列)を使用してCatsクラスのインスタンスaisatsuが作成されているので > cin>> x;//変数xにキーボードで書いた文字列を入れる としたところでaisatsuには影響はない。(aistau.nakuはコンストラクタで代入したまま=空文字)

nery1024
質問者

お礼

なるほど。 要するに、既にからっぽの変数を読み込んでるから、あとから変数に文字を入力したとしても、反映されないで関数nakuを呼び出してたって事ですか。 わかりやすかったですありがとうございました!

関連するQ&A

  • C++の関数

    関数の課題が出たんですが分からないので教えてください。 第1引数と第2引数はchar型の1元配列であり、これら2つの配列(文字列)を連続して表示する関数catstringがあるものとする。 ただし第2引数にはデフォルトの文字列"あいうえお"が設定されている。main関数からキーボード入力で2つの文字列を取得し、 catstringの第1引数のみに文字列が渡される場合と第1、2引数ともに文字列が与えられるプログラムを作成せよ。 やってみましたがエラーが出てしまいます。 #include <iostream> #include <cstdlib> using namespace std; char catstring(char,char="あいうえお"); int main() { char a,b; cin>>a; cin>>b; cout<<catstring(a)<<endl; cout<<catstring(a,b)<<endl; return EXIT_SUCCESS; } char catstring(char x,char y) { char s; s=x+y; return(s); }

  • メンバ関数の引数としてオブジェクトの配列をとれる?

    VC++6.0 on W2Kを使っている初心者です。 表題のとおりですが、具体的なプログラムは下のようです。 また、*部分に相当するところもエラーになるのですが、 どのように変えればよいのでしょうか? なお、プログラムの内容そのものには意味はなく 単に動作確認のためのサンプルです。 実行すると、 「How many cats do you create?」 と聞かれるので、数字を入力すると、 Nekoオブジェクトが生成され、i番目の猫にはiという名が付けられます。 そして、「何匹目を鳴かせますか?」と聞かれるので、 数字を入力すると、 「My name is i-th cat.」 と答えられ、さらに、Inuが、 「i-th cat is tasty.」 と答える、という内容になっています。 #include <iostream> #include <string> using namespace std; class Neko { int name; public: Neko(){} Neko(int n):name(n){} void setname(int n){name=n;} int getname(){return name;} void naku(int n) const; }; void Neko::naku(int i) const { cout <<"My name is "<<getname()<<"th cat."<<endl;・・・* } class Inu { public: Inu(){} void naku(int i) const; }; void Inu::naku(int i)const{ cout <<i<<"th cat is tasty."<<endl; } int main() { int i; int num; int temp; Neko *x; Inu y; cout <<"How many cats do you create?"<<endl; cin >>num; x=new Neko[num]; for(i=0;i<num;i++){ x[i].setname(i); } cout <<"何匹目を鳴かせますか?"<<endl; cin >> temp; x[temp].naku(); y.naku(temp); }

  • 質問です。。。

    いつもすみません。また質問させていただきます。 まずしたのプログラムを見てください・・・ #include <iostream> #include <string> using namespace std; int main() { string name; int tosi; cout << "こんにちは。私はコンピュータです。" <<endl; cout << "あなたの年齢を教えてください" <<endl; cin >> tosi; cout<<name<<"歳なんですか・・・老けてますね(笑)"<<endl; cout << "どこの学校ですか" <<endl; cin >> name; cout<<name<<"That's right!"<<endl; } このプログラムの8行目にあるint tosi;がありますよね。 この単語がなくても string name があったら12行目のプログラムができたのですが、どういうことなのでしょうか? 表現が一部変ですがよろしくお願いします。

  • vectorに格納されたオブジェクトの廃棄

    次のようなテストプログラムを作ってみました。 OSはVineです。 #include <iostream> #include <string> #include <vector> using namespace std; class Neko{ string name; public: Neko(){} Neko(string n):name(n){} void SetName(string n){name=n;} void Naku() const; }; void Neko::Naku() const{ cout << "名前は" << name << endl; } int main(){ int i; int num; string temp; vector <Neko> x; for(i=0;i<num;i++){ Neko *y=new Neko; x.push_back(*y); } for(i=0;i<num;i++){ cout << "名前を入力" << endl; cin >> temp; x[i].SetName(temp); } for(i=0;i<num;i++)x[i].Naku(); delete [] x;・・・※ } 廃棄(※のところ)するとき、これでは コンパイルエラーになってしまいます。 for文で回しても同じです。 どのように書けばよいのでしょうか? vectorにはポインタではなくオブジェクトが 入っていることに注意してください。

  • stringクラスのオブジェクト

    C++にて下記のソースをVC++にてコンパイルすると「'string'定義させていない識別子です。」などどエラーがでてしまいます。BC++では何も問題ないのですが・・・。なぜなのでしょうか? #include <iostream.h> #include <string.h> void main(){ string s; cout << "貴方の名前は?" <<endl; cin >> s; cout << s <<"さん、こんにちは"<<endl; }

  • VC++でプログラムの勉強をしています。

    プログラムは最近はじめたばかりです。While文とif文を使ってクイズを作ってみたところ、一個目のsinで入力を求めているところから無限ループになってしまいました。色々調べてcin.cler()とsin.ignore()を入れたりもしてみましたが上手くいきませんでした。どこを間違えているのでしょうか? //クイズ #include <iostream> using namespace std; int main()//cin.clear();cin.ignore();???? { int a; int b; while(1) { cout<<"ネコ型のロボットが出てくるアニメといえば?"<<endl; cout<<"A)ドラえもん B)ドラエもん C)ほりえもん D)サザエさん"<<endl; cin>>a; if(a=='A') { cout<<"ファイナルアンサー?"<<endl; cout<<"Y)Yes N)NO"<<endl; cin>>b; if(b=='Y'){break;} if(b=='N'){cout<<"ゆっくり考えてね!!"<<endl;} if(b!='Y'||'N'){cout<<"正しく入力してね!"<<endl;} } if(a=='B'||'C'||'D') { cout<<"ファイナルアンサー?"<<endl; cout<<"Y)Yes N)NO"<<endl; cin>>b; if(b=='Y'){cout<<"残念!!"<<endl;} if(b=='N'){cout<<"ゆっくり考えてね!!"<<endl;} } if(a!='A'||'B'||'C'||'D'){cout<<"正しく入力してね!"<<endl;} } cout<<"正解!!"<<endl; }

  • C++文字列の挿入、結合のコードについて

    実行結果のような出力をするためには、 以下のコードの(ウ)(エ)(オ)の部分には何を入れたらよいのでしょうか? よろしくお願いします。 #include <iostream> #include <string> using namespace std; int main( ) { string str1="ABCDEF"; string str2="0123"; string str3; string q; do { (ウ) ; cout << str3 << endl; (エ) ; cout << str1 << endl; cout << "quit?"; cin >> q; } while ( (オ) ); cout << "終了" << endl; return 0; } <実行結果(出力結果)> ABCDEF0123 ABC123DEF quit?q ABC123DEF0123 ABC123123DEF quit?qu ABC123123DEF0123 ABC123123123DEF quit?quit 終了

  • このプログラムを...

    現在テスト用のプログラムを書いているのですが、なかなか動いてくれません。 ソース: #include <iostream> #include <iomanip> #include <string> using namespace std; struct MovieData { string title; string director; int year; int time; }; const int ARRAY_SIZE = 2; void showItem(MovieData[ARRAY_SIZE]); int main() { MovieData part[ARRAY_SIZE]; for (int cnt = 0; cnt < ARRAY_SIZE; cnt++) { cout << "Enter the movie's name: "; cin >> part[cnt].title; cout << "Enter the director's name: "; cin >> part[cnt].director; cout << "Enter the year of release: "; cin >> part[cnt].year; cout << "Enter the movie's running time: "; cin >> part[cnt].time; } showItem(part); return 0; } void showItem(MovieData part) { cout << fixed << showpoint << setprecision(2); for (int cnt2 = 0; cnt2 < ARRAY_SIZE; cnt2++) { cout << "Name of movie: " << part[cnt2].title << endl; cout << "Director: " << part[cnt2].director << endl; cout << "Year of released: " << part[cnt2].year << endl; cout << "Running time: " << part[cnt2].time << endl; } } どこが間違っているのでしょうか?宜しくお願いします。

  • Visual C++ 2008 Express Editionで作ったプログラムがコンパイルできない

    http://www.asahi-net.or.jp/~yf8k-kbys/newcpp3.html このサイトに掲載されていたプログラムをまねて以下のプログラムをかいてみたのですがコンパイルが通りません。 原因などはどこにあるのか教えていただけないでしょうか。 // test003.cpp : メイン プロジェクト ファイルです。 #include "stdafx.h" //using namespace System; using namespace std; int main(array<System::String ^> ^args) { string name; //Console::WriteLine(L"Hello World"); //return 0; cout << "こんにちは。私はコンピュータです。" << endl; cout << "あなたの名前を入力してください。" << endl; cin >> name; cout << name <<"さん。よろしく。" << endl; }

  • 結果を報告しない?(void)

    #include<iostream> #include<string> using namespace std; void Aisatu(string n){ cout<<n<<"さん、こんばんわ"<<endl; } int main() { Aisatu("鈴木"); } 上のプログラムで、C++の学習書に「void」とは「この関数は結果をどこにも報告しない、ということ」と書いてありますが、私の理解では下のAisatu("鈴木");という外部の文字列を受け取りcout<<nに「報告」しているように感じられます。どうか解釈がうまくいきますようにご教授いただけないでしょうか。よろしくお願いします。

専門家に質問してみよう