C ++虚函数基于返回类型的建议

时间:2012-11-08 09:29:41

标签: c++ oop polymorphism virtual return-type

我需要一个基类,它给我原始类型的数据指针。我在其中添加了一个功能。我派生了类的类型。我使用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;
}

2 个答案:

答案 0 :(得分:2)

使基类成为模板类,数据类型为模板变量

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

class derivedAType : public base<int>

但是这会将基类更改为模板类,这意味着您无法将它们存储在一起,base<int>base<short>不同

如果这是不可接受的,其他选项只比你的代码更清晰但是相同,请参考this question。基本上派生类返回类型可以反映它们的真实类型,我认为它应该自动转换为void*,所以你不必手动投射指针。

答案 1 :(得分: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;
}

当然,您可以通过存储创建的打印回调并使用它两次来简化这一过程。