2

私には、リーダーとライターの2つのクラスがあります。データソース/ターゲットは柔軟である必要があるため、両方のクラスで抽象インターフェイスがあります。

class abstract_reader {
...
};

class concrete_reader : public abstract_reader {
   DATATYPE m_data;
...
};    
class abstract_writer {
...
};

class concrete_writer : public abstract_writer {
   DATATYPE m_data;
...
};

ライターは、読み取りと書き込みの両方の機能を備えている必要があります。concrete_writerの読み取り部分の実装は、concrete_readerの実装と同じです。これらのクラスを組み合わせる良い方法は何でしょうか?

4

4 に答える 4

2

必要なのは少し紛らわしいですが、いくつかの方法があります。

  • 両方の抽象クラスからライターを導き出します
  • ライターで具体的なリーダーへのポインターを保持します
  • ライターで具体的なリーダーのインスタンスを保持します
  • ライターから読み取り機能を削除し、読み取りと書き込みの両方が可能な3番目のクラスを作成します。

個人的には、私は最後の方法に従います。そうすれば、読み取り専用、書き込み専用、およびその両方を行うためのクラスの完全なセットが得られます。

于 2012-08-14T13:53:34.053 に答える
1

なぜ作家は読み方を知りたがるのでしょうか。おそらく、読み取り機能と書き込み機能の両方を組み込んだ3番目のクラスについて考える必要があります。

大丈夫だと確信している場合は、との両方からライターを導き出すだけabstract_readerですabstract_writer。それらが適切に実装されたインターフェース(たとえば、フィールドなし)である限り、すべてが正常に機能するはずです。

そして、ああ、多分テンプレートを組み込むのがいいでしょう(私は不思議に気づきましたDATATYPE

于 2012-08-14T13:51:25.407 に答える
1
class concrete_writer : public abstract_writer, public abstract_reader {
public:
    void read() { // or whatever the proper override is for abstract_reader
        reader.read();
    }
private:
    concrete_reader reader;
};

しかし、@ Bartekが指摘したように、「writer」という名前のクラスがあり、それも読み取るのは奇妙に思えます。

于 2012-08-14T13:54:15.707 に答える
1

まず、それが単なるの場合writer、それは読み方を知らないはずです。画面にライターを実装するとどうなりますか?それでも、と ReaderWriterに加えて、ReaderWriter使用することは非常に合理的な選択であり、同じ問題が発生します。

私がこれを行う方法は、最初に、との両方から継承するインターフェイスとしてを定義することReaderWriterです。ReaderWriter

class Reader
{
private:
    //  Pure virtual functions to the implementation...
public:
    virtual ~Reader() {}
    //  Interface...
};

class Writer
{
private:
    //  Pure virtual functions to the implementation...
public:
    virtual ~Writer() {}
    //  Interface...
};

class ReaderWriter : public virtual Reader, public virtual Writer
{
    //  Just joins the two; adds nothing new of its own
};

仮想継承に注意してください。これは通常、インターフェイスを拡張するときのデフォルトです。それができたら、(通常は)実装にミックスインを使用できます。

class ConcreteReader : public virtual Reader
{
    //  Overrides for the pure virtual functions, + any data needed.
public:
    ConcreteReader();   //  Or with parameters, as needed.
};

class ConcreteWriter : public virtual Writer
{
    //  Overrides for the pure virtual functions, + any data needed.
public:
    ConcreteWriter();   //  Or with parameters, as needed.
};

class ConcreteReaderWriter : public ReaderWriter, public ConcreteReader, public ConcreteReaderWriter
{
};

を受け取るクライアントコードReader*は読み取ることができます。缶を受け取るクライアントコードWriter*は書くことができます。を受信するクライアントコード ReaderWriterはどちらでも実行できます。そしてもちろん、クライアントがを持っている場合 Reader*、それは常にまたは にdynamic_castそれを試みることができ、dynamic_castが成功した場合、それは同様に書き込むことができます。Writer*ReaderWriter*

編集:私は言及するのを忘れました:このテクニックはミックスインとして知られています。

于 2012-08-14T14:22:48.897 に答える