C++を始めてもうすぐ一ヶ月になり、今までの知識とこれから得る知識を1つのプロジェクトに
入れ込んでいこうと思い哺乳類クラスをトップとするものを作り始めました。
哺乳類→動物→猫があり、猫レベルのクラスにstring nameを持たせ、setname、getnameの関数を
作ると、同様の関数をこのレベルのクラスに作ることになり、それを避ける為に上位クラスに
nameを持たせようとも思ったのですが、哺乳類クラスや動物クラスがnameを持つことが
ピンときませんでした。
そこでNameクラスを作ってデータメンバとして持たせることを考えましたが、publicでなければ
結局Nameクラスのデータメンバにアクセスする為の関数をpublicに作らなければなりません。
最初に戻ってしまいました。
「クラスの責任はそのクラスが負う」というのなら、猫クラスはNameクラスをpublicで持っても
いいのかなと思って、何かないのかなと思って検索してみたのですが、クラスのデータメンバも
privateで持ち、その関数をpublicでというコードばかりでした。
やはりデータメンバはクラスであってもpublicにしないというのが基本のようです。
皆さんはこのような場合、どのような方法を取られるのでしょうか、よろしくお願い致します。
データメンバのクラスをpublicで持ってもいいのでしょうか?
Re: データメンバのクラスをpublicで持ってもいいのでしょうか?
動物などの抽象的なものが具体的な名前を持つのが不自然、ということでしょうか。豆電球 さんが書きました:哺乳類クラスや動物クラスがnameを持つことが
ピンときませんでした。
でしたら、nameという具体的なものを動物クラスで持たせず、派生先で持たせて、親クラスに具体的なものを扱う為の仮想関数を書いておけばよいのではないでしょうか。
class Animal
{
public:
/* コンストラクタ・デストラクタは省略 */
virtual void SetName( const std::string& name ) = 0;
virtual std::string GetName() const = 0;
};
class Cat : public Animal
{
std::string m_name;
public:
/* コンストラクタ・デストラクタは省略 */
virtual void SetName( const std::string& name ) override
{
m_name = name;
}
virtual std::string GetName() const override
{
return m_name;
}
};
触れる必要のないものには触れないようにする、が基本でしょう。豆電球 さんが書きました:「クラスの責任はそのクラスが負う」というのなら、猫クラスはNameクラスをpublicで持っても
いいのかなと思って、何かないのかなと思って検索してみたのですが、クラスのデータメンバも
privateで持ち、その関数をpublicでというコードばかりでした。
やはりデータメンバはクラスであってもpublicにしないというのが基本のようです。
少なくともわたしは、データメンバはpublicにはしません。
publicにするのは、const / constexpr を使用した定数などです。
それ以外はgetterを介して取得します。
内容を読み間違えていましたら申し訳ないです。
初心者です
Re: データメンバのクラスをpublicで持ってもいいのでしょうか?
Rittai_3Dさん、ありがとうございます。
やはり、アクセサを書くというのが基本ですなのですね。
猫、犬などそのレベルのクラスに同様の関数を書かずにNameクラスで処理できないかと
考えてしまいました。
こうすれば、同様の関数を猫、犬などのクラスレベルに書かなくてもいいかなと思ってしまったのです^^;
この考え方はダメそうですね^^;
やはり、アクセサを書くというのが基本ですなのですね。
猫、犬などそのレベルのクラスに同様の関数を書かずにNameクラスで処理できないかと
考えてしまいました。
// mainStart.cpp
#pragma warning(disable:4996)
#include <iostream>
#include "mammal.h"
using namespace std;
int main()
{
Cat tama("たま");
cout << tama.name.getName() << endl; // CatのnameをpublicにすればOKだけど。。。
::system("pause");
return 0;
}
// mammal.h
// class--> Mammal,Person,Cat
// class--> include"has_a.h"(Name)
#pragma once
#include <iostream>
#include <string>
#include "has_a.h"
using namespace std;
// Mammal class
class Mammal
{
private:
int sex;
public:
void setSex(int a_sex);
int getSex()const;
};
// Cat class-----
class Cat :public Mammal
{
protected:
private:
public:
Name name; // has_a Nameクラスの責任はNameクラスが負うのでPublicでも問題ないのでしょうか?
public:
Cat(string a_name);// : name(a_name);は実装に書く。プロトタイプには書かない。
};
// Person class-----
class Person :public Mammal
{
private:
Name name; // has_a
public:
};
// inline--------------インライン関数はヘッダーファイルに書く。
// Mammal実装+++++
inline void Mammal::setSex(int a_sex)
{
if (((unsigned int)a_sex) > 2){ sex = 0; } // 0=不明、1=男(雄)、2=女(雌)
sex = a_sex;
}
inline int Mammal::getSex()const
{
return sex;
}
// Animal実装+++++
// Cat実装+++++
inline Cat::Cat(string a_name) : name(a_name) // Nameクラスのコンストラクタを呼び出し
{
// 他は何もしない
}
// Person実装+++++
#pragma once
#pragma warning(disable:4996)
#include <iostream>
#include <string>
using namespace std;
// Name class-----
class Name
{
private:
string name;
public:
Name(string a_name);
void setName(string a_name);
string getName()const;
};
// inline ------------------------------------------------------------
// Name実装+++++
inline Name::Name(string a_name) // 名前を引数に取るコンストラクタ
{
name = a_name;
}
inline void Name::setName(string a_name)
{
name = a_name;
}
inline string Name::getName()const
{
return name;
}
この考え方はダメそうですね^^;
Re: データメンバのクラスをpublicで持ってもいいのでしょうか?
これ、ぱっと見た時に違和感を感じませんか?個人的には"name.getName()"でnameが被っているのが気になります。 で十分意味が通りますし。
よくないと思います。
例えば、
// いろいろ省略
int main()
{
Cat tama( "たま" );
tama.name = Name { "Rittai_3D" };
cout << tama.name.getName() << endl;
}
簡単に変数が書きかえられることはよくないです。隠ぺいしましょう。
オフトピック
ヘッダファイルに using namespace std; はちょっと・・・。
初心者です
Re: データメンバのクラスをpublicで持ってもいいのでしょうか?
「名前のある哺乳動物」を作るのではだめなんでしょうか.
哺乳動物→名前のある哺乳動物→猫
哺乳動物→名前のある哺乳動物→犬
哺乳動物→河童 (あえて名前をもたないとする良い例が思いつかない…)
哺乳動物→名前のある哺乳動物→猫
哺乳動物→名前のある哺乳動物→犬
哺乳動物→河童 (あえて名前をもたないとする良い例が思いつかない…)
オフトピック
>やはりデータメンバはクラスであってもpublicにしないというのが基本のようです。
「みんながやってるから → 自分もそうやる」
とかじゃなくて
「そのようにしている理由のようなものを自分で把握したから → 結果として自分もそうやる」
という形でありたいですね.
「みんながやってるから → 自分もそうやる」
とかじゃなくて
「そのようにしている理由のようなものを自分で把握したから → 結果として自分もそうやる」
という形でありたいですね.
Re: データメンバのクラスをpublicで持ってもいいのでしょうか?
Rittai_3D さん、物凄く納得です^^
usaoさん、ありがとうございます。
まだまだ、やっと真似をするというレベルなのでこれから頑張ります^^
Rittai_3D さん、usaoさん、ありがとうございました。
usaoさん、ありがとうございます。
まだまだ、やっと真似をするというレベルなのでこれから頑張ります^^
Rittai_3D さん、usaoさん、ありがとうございました。