クラス等を使ってソースを書く練習中なのですが、思ったように結果が出ません。
#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; // これを付け足してください
}
なるほど。
めちゃくちゃわかりやすいです。
ヘッダーファイルを出力するやり方とか、#ifdefとかはまだ覚えてないので、もう少し勉強が進んでからこの回答を参考にさせていただきますね。
return 0;
は了解です。
ありがとうございました!
No.4
- 回答日時:
コンストラクタでメンバー name に値を設定するときには
Cats(string x)
: name(x)
{
}
のように「初期化」をする方がよいです. デフォルトコンストラクタは不要なら定義しなくていいです.
ちなみに「_+大文字」とか「__」とかで始まる識別子を使うのは危険かもしれない.
おっととと, なんでクラス名が Cats と複数形なんだろう?
>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;
}
を書いておくべきだと、思います。
ここに書いたのは、あくまで、私個人のコーディング慣習ですから、このような書き方があるというように理解してほしいです。
この回答への補足
とても興味深いのですが、理解しきれてません。
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;
・
・
・
の様に記述すればいいのでしょうか?
No.1
- 回答日時:
> Cats aisatsu(x);//クラスCatsのメンバーaisatsuを作る(中身は文字列の変数x)
の時点でx(この時点で空文字列)を使用してCatsクラスのインスタンスaisatsuが作成されているので
> cin>> x;//変数xにキーボードで書いた文字列を入れる
としたところでaisatsuには影響はない。(aistau.nakuはコンストラクタで代入したまま=空文字)
なるほど。
要するに、既にからっぽの変数を読み込んでるから、あとから変数に文字を入力したとしても、反映されないで関数nakuを呼び出してたって事ですか。
わかりやすかったですありがとうございました!
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# C++のcinの動作 5 2023/02/26 00:13
- C言語・C++・C# C++プログラミングコードにポリモーフィズムを取り入れ方を教えてください。 2 2023/06/09 11:17
- Visual Basic(VBA) 集めたシートのシート名を変更したい。 下記のコードでサブフォルダにあるファイルのSheet3を集めて 6 2022/08/23 10:38
- C言語・C++・C# C++初心者です stirng 2 2022/09/20 20:43
- Java Javaの問題なのですが、「3文字以上の英数字文字列を入力し、文字列の中に文字(9)が出てくるまでの 1 2023/06/06 18:55
- C言語・C++・C# プログラミングの問題です。至急教えてください。 /***から***/の部分をプログラミングにしてほし 1 2022/10/13 11:48
- Visual Basic(VBA) サブフォルダ(データ)にある複数の.xlsxファイルのSheet3のA2セルの値で01から左側をB2 2 2022/08/14 15:46
- C言語・C++・C# 至急教えてください。プログラミングの問題です。 malloc関数を使ってください!お願いします! 最 1 2022/07/21 09:28
- JavaScript Javascriptが機能せず原因が分からないので教えて頂きたいです 3 2023/06/04 14:50
- Java java final 1 2022/06/10 22:49
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
FriendとPublicの違い。。。
-
既定のコンストラクタがない?
-
【ASP.NET】 独自で作成したク...
-
C++/CLIからC++の呼び出しで例外
-
オーバーライド関数の呼び出し...
-
(UWSC) 「#32770」の意味わかり...
-
MessageBoxを継承したい
-
C++で継承元のクラスの代入演算...
-
MFC 分割ウィンドウのそれぞれ...
-
クラスのアドレスを引数として...
-
モーダレスなメッセージボック...
-
OnInitDialog()の関数の組み込み方
-
VBのシステムの設計書にUMLは適...
-
VC++ リストボックスにデータを...
-
【C++】vectorについて
-
CDocumentの取得方法について
-
DataGridViewのセルに斜線を引...
-
VC++ 7.1 で メインウィンドウ...
-
エディットコントロールのイベ...
-
[MFC] CWnd::MessageBoxの警告...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
FriendとPublicの違い。。。
-
既定のコンストラクタがない?
-
(UWSC) 「#32770」の意味わかり...
-
クラスのアドレスを引数として...
-
エディットコントロールのイベ...
-
ダイアログ表示時にチェックボ...
-
イベントにAddHandlerされてい...
-
ダイアログクラスのコントロー...
-
C++ protectedにアクセス不可
-
DebugクラスとTraceクラスの違い
-
DataGridViewのセルに斜線を引...
-
【ASP.NET】 独自で作成したク...
-
このコンパイルエラーの意味に...
-
エディットコントロールでEnter...
-
継承を重ねた場合のコストはど...
-
C#で通常のbuttonコントロール...
-
ボタンのオーナードローについて
-
MFCのCListCtrlでスクロールを検出
-
【C++】相互参照
-
SetTimerの行でアサートエラー...
おすすめ情報