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>

如果这是不可接受的,其他选项只是比您的代码更干净一点,但基本相同,请参阅此问题。基本上派生类返回类型可以反映它们的真实类型,我认为它应该自动转换为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;
}

当然,您可以通过仅存储创建的打印回调并使用它两次来简化此操作。

于 2012-11-08T10:01:19.397 回答