アプリ版:「スタンプのみでお礼する」機能のリリースについて

今C++でクラスの設計をしています。
どう設計すれば、いいか分からないので、しっている方に教えていただきたいですが。

class A{
private:
int id;
public:
int getId();
void setId();
};


class B{
private:
int id;
public:
int getId();
void setId();
}


class C{
private:
int id;
public:
int getId();
void setId();
}

この三つのクラスが、共通な機能があります。また、実装も同じで、
継承を利用して、どう設計すれば、いいですか?

よろしくお願いします。

A 回答 (4件)

継承でなく委譲(#3の回答のようなやり方)を使うのは、一般に


「インタフェースと実装の分離」という方針によるものと推測します。

他言語では"interface"というものが明示的に存在したり、
多重継承に制限があったりするので良くある手ですが、
C++の場合は、実装の継承にprivateな継承を使う手もなくはないです。
> class A: classD
↑こういう形ですね。
この場合のポイントは、class A : public classDではなく、class A : (private) classDであること。

classDとして扱われない(classDはただの実装用の存在であって、
設計上、classDとして扱われることを想定していない/べきでない)ということですが。

(以下、蛇足)

ちなみに、「できるだけclass」がもしstructのことをさしているなら(違ったら失礼)、
C++のstructはclassの一種でデフォルトがpublic:なものに過ぎず、
struct IInterface
{
  ↓こう読み替えても大差なし。
class IInterface
{
public:

# 後、C++でスマートポインタを否定すると旨みが減りますね。
# 例外脆弱なコードになりがちですし…。
    • good
    • 0

>class A: classD


>class B: classD
>class C: classD
>
> 以上の形にすることでしょうか?

いいえ

class A {
 D d_;
public:
 ...
};

な風にするということです。
    • good
    • 0
この回答へのお礼

返事ありがとうございました。

指摘されていた形にする理由は?

お礼日時:2009/01/31 17:43

 こんにちは。

こんな感じでしょうか。参考程度に。

struct IInterface
{
virtual ~IInterface(){}
virtual int getId() = 0;
virtual void setId(/*???*/) = 0;
};

struct CInterface : public IInterface
{
protected:
CInterface(int id_) : id(id_)
{}

virtual int getId(){ return this->id; }
virtual void setId(/*???*/){ /*this->id = ???*/; }

private:
int id;
};

struct A : public CInterface
{
static std::auto_ptr<IInterface> CreateInstance(int id){ return new A(id); }
private:
explicit A(int id_) : CInterface(id_)
{}
};

struct B : public CInterface
{
static std::auto_ptr<IInterface> CreateInstance(int id){ return new B(id); }
private:
explicit B(int id_) : CInterface(id_)
{}
};

struct C : public CInterface
{
static std::auto_ptr<IInterface> CreateInstance(int id){ return new C(id); }
private:
explicit C(int id_) : CInterface(id_)
{}
};

int main(void)
{
std::auto_ptr<IInterface> aptr[] = {A::CreateInstance(1), B::CreateInstance(2), C::CreateInstance(3)};

for(int i = 0; i < sizeof(aptr) / sizeof(aptr[0]); ++i)
{
cout << aptr[i]->getId() << endl;
}

return 0;
}

この回答への補足

返事していただいて、ありがとうございました。

追加したいですが、ちょっとスマートポインタを使いたくないです。
また、できるたけ、classで実装したいということです。

すみませんが、ありがとうございました。

補足日時:2009/01/31 17:29
    • good
    • 0

実装を継承したい場合は C++ の文法で言う継承はせずに、


共通の実装クラスを個別のクラスでメンバ変数として保持するのが普通だと思います。
    • good
    • 0
この回答へのお礼

ちょっと、くわしく教えていただけませんか?
例えば、class D を作る。
class D{
protected:
int id;
public:
int getId();
void setId();
}

class A: classD
class B: classD
class C: classD

以上の形にすることでしょうか?
あるいは、もっといい設計がないしょうか?

お礼日時:2009/01/31 17:13

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!