【问题标题】:C++ virtual functions base return type suggestionsC++ 虚函数基本返回类型建议
【发布时间】:2012-10-28 11:31:20
【问题描述】:

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

【问题讨论】:

  • 你只有C++内置类型?
  • 只是不...使用模板
  • 课程还有其他区别吗?如果没有,您可以使用tempaltes。
  • 我不能使用模板,因为我想将它们全部存储在一个容器中。

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


【解决方案1】:

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

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

class derivedAType : public base<int>

但这会将基类更改为模板类,这意味着您不能将它们存储在一起,base&lt;int&gt;base&lt;short&gt; 不同

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

【讨论】:

  • 是的,这不是我想要的,因为我想将它们存储为 std::vector _v;
  • 但是如果您不知道它们返回的是什么类型,您将如何使用它们?
  • 你可以给他更多关于如何使用它的示例代码。 :P
  • @KarthikT 我不想决定将它们存储在哪种类型。我想实时决定它和流程的不同部分。对象的创建地点、存储地点和调用地点是不同的。我不想知道我在商店里有哪种类型。
  • 那么我想不出比类型枚举更聪明的方法了,它告诉您它是什么类型,以及一个 IsType() 函数来查找它是否属于该类型。您的每个派生类都会正确响应该调用,让您知道数据的类型,您可以进行相应的转换。
【解决方案2】:

不确定您的问题。但也许双重回调会有所帮助:

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;
}

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

【讨论】:

  • 感谢您的建议!在这种方法中,我需要在派生自 Callback 的类中执行每个算法。它不适合我的情况。我需要从这个机制之外获得类型的指针。
猜你喜欢
  • 2011-06-07
  • 1970-01-01
  • 1970-01-01
  • 2019-08-11
  • 2014-01-02
  • 1970-01-01
  • 2023-01-20
  • 1970-01-01
相关资源
最近更新 更多