2

プリミティブ型のデータのポインターを提供する基本クラスが必要です。その中に機能を追加します。クラスの型を派生させました。戻り値の型としてすべてのプリミティブ型をサポートするために void * を使用しましたが、古い C 時代のようなものです。OOPには不向きです。OOPで適切な方法で行うべき提案はありますか?

#include <iostream>

class base {
public:
    virtual void *getPtr() = 0;
    virtual ~base() {};
};

class derivedAType : public base {
protected:
    int _i;
public:
    derivedAType(int i): _i(0) { _i = i; };
    virtual ~derivedAType() {}

    virtual void *getPtr() {
        return static_cast<void *>(&_i);
    }
};

class derivedBType : public base {
protected:
    short _s;
public:
    derivedBType(short s): _s(0) { _s = s; };
    virtual ~derivedBType() {}

    virtual void *getPtr() {
        return static_cast<void *>(&_s);
    }
};

int main()
{
    base *b1 = new derivedAType(1203912);
    base *b2 = new derivedBType(25273);

    std::cout   << "b1 : "   << *(static_cast<int *>(b1->getPtr()))
                << "\nb2 : " << *(static_cast<short *>(b2->getPtr()))
                << std::endl;

    delete b2;
    delete b1;

    return 0;
}
4

2 に答える 2

2

基本クラスを、データ型をテンプレート変数として持つテンプレートクラスにします。

template<typename DataType>  
class base {
virtual DataType* getPtr() = 0;
//...
};

class derivedAType : public base<int>

ただし、これにより、基本クラスがテンプレートクラスに変更されます。つまり、それらを一緒に保存することはできませんbase<int>base<short>

これが受け入れられない場合、他のオプションはコードよりも少しクリーンですが、同じです。この質問を参照してください。基本的に派生クラスの戻り型はTrueTypeを反映でき、自動的にに変換されるはずvoid*なので、手動でポインターをキャストする必要はありません。

于 2012-11-08T09:31:19.937 に答える
0

あなたの問題がわからない。しかし、二重のコールバックが役立つかもしれません:

class Callback {
public:
  virtual void do_int( int i ) const = 0;
  virtual void do_short( short s ) const = 0;
  /* ... */
}

class base {
public:
    virtual void do_stuff(const Callback & c); /* will need a more telling name */
    virtual ~base() {};
};

class derivedAType : public base {
protected:
    int _i;
public:
    derivedAType(int i): _i(0) { _i = i; };
    virtual ~derivedAType() {}

    virtual void do_stuff(const Callback & c) {
        c.do_int( _i );
    }
};

class derivedBType : public base {
protected:
    short _s;
public:
    derivedBType(short s): _s(0) { _s = s; };
    virtual ~derivedBType() {}

    virtual void do_stuff( const Callback & c) {
        c.do_short( _s );
    }
};

class print_callback : public Callback {
public:
  virtual void do_int( int i ) const { std::cout << i; }
  virtual void do_short( short s )  const { std::cout << s; }
}

int main() {
  base *b1 = new derivedAType(1203912);
  base *b2 = new derivedBType(25273);



  std::cout   << "b1 : ";
  b1->do_stuff(print_callback());
  std::cout << "\nb2 : ";
  b2->do_stuff(print_callback());
  std::cout << std::endl;

  delete b2;
  delete b1;

  return 0;
}

もちろん、作成した print コールバックを保存し、それを 2 回使用するだけで、これを単純化できます。

于 2012-11-08T10:01:19.397 に答える