C++ 如何创建模板参数为抽象基类的队列?

C++ 如何创建模板参数为抽象基类的队列?,c++,c++11,queue,abstract-class,C++,C++11,Queue,Abstract Class,我的程序需要一个FIFO队列来保存所有这些事件。这些事件应为不同的用户定义类型,但队列需要一个模板参数。所以我想我会使用一个抽象基类。此外,这还可以强制派生类具有我想要的函数签名 但是,当我尝试以下操作时,我会通过std::queue::front检查队列的元素,但它不允许我调用这些元素的虚拟函数 #include <iostream> #include <queue> class Base { public: virtual double returnNum(

我的程序需要一个FIFO队列来保存所有这些事件。这些事件应为不同的用户定义类型,但队列需要一个模板参数。所以我想我会使用一个抽象基类。此外,这还可以强制派生类具有我想要的函数签名

但是,当我尝试以下操作时,我会通过
std::queue::front
检查队列的元素,但它不允许我调用这些元素的虚拟函数

#include <iostream>
#include <queue>

class Base
{
public:
    virtual double returnNum() {};
};

class InfoChunk : public Base
{
private:
    double m_num;
public:
    InfoChunk(const double& arg) : m_num(arg) {};
    double returnNum() {return m_num;};
};

int main(int argc, char **argv)
{

    std::queue<Base> q;
    InfoChunk info(.2);
    q.push(info);
    while(!q.empty()){
        std::cout << q.front().returnNum() << "\n";
        q.pop();
    }    

    return 0;
}
#包括
#包括
阶级基础
{
公众:
虚拟双returnNum(){};
};
类InfoChunk:公共基
{
私人:
双m_数;
公众:
InfoChunk(constdouble&arg):m_num(arg){};
double returnNum(){return m_num;};
};
int main(int argc,字符**argv)
{
std::队列q;
信息块信息(.2);
q、 推送(信息);
而(!q.empty()){

std::cout要使基成为抽象的,它至少需要纯虚函数。此外,代码编译的原因是
base
是可切片的。这意味着当将派生部分分配给base时,派生部分将丢失,因为默认情况下只复制base的成员

为了实现您想要的,您需要使用一个指针队列(当派生指针自动转换为基本指针-多态性兼容时),最好是一个智能指针,如shared_ptr,它已经为您执行了必要的内存管理

下面的示例代码实现了您想要的功能

#include <queue>
#include <memory>

struct Base
{
  virtual void foo() = 0;
  virtual ~Base(){}
};

struct Derived : Base
{
  void foo() override{}
};

int main() {

    std::queue<std::shared_ptr<Base>> xq;
    xq.push(std::make_shared<Derived>());
    Base& x = xq.back();
    xq.pop();
    return 0;
}
#包括
#包括
结构基
{
虚拟void foo()=0;
虚拟~Base(){}
};
派生结构:基
{
void foo()重写{}
};
int main(){
std::队列xq;
推送(std::make_shared());
Base&x=xq.back();
xq.pop();
返回0;
}
您也可以只使用普通指针,但这意味着您需要提供自己的内存管理(例如:

intmain(){
std::队列xq;
推送(新衍生);
Base*x=xq.back();
xq.pop();//注意:在弹出之前不要删除。。。
删除x;//或保留它
返回0;
}

您不能按值存储对象,而期望多态行为。您必须按(可能是智能)存储对象指针。另请参见:@IgorTandetnik这与我前几天刚问到的某个问题有关。看起来我对这些东西不感兴趣。感谢您的帮助--我将搜索更一般的结果,讨论多态性和指针之间的关系。此外,您的
Base
类并不是抽象的,因为它实现了所有函数s、 抽象地说,它应该有
=0;
而不是函数体
{}
。我不清楚
X
是基类还是派生类。我想我想要类似
std::queue xq;
的东西,对吧?对于之后的那一行…我如何将一个已经生成的派生对象转换为(智能)对象指针,指向正确的类型?这里的方式是将空白对象推送到队列上。可能类似于
xq.push(std::make_shared(预先存在的bjofderivedtype))
为了在您的上下文中更清晰,我修改了我的示例。请让我知道这是否更清晰。您会注意到,派生从Base公开派生,但共享的ptr用作队列中的多态类型。也可以使用普通的Base*,但这意味着您必须添加自己的内存管理
int main() {

    std::queue<Base*> xq;
    xq.push(new Derived);
    Base* x = xq.back();
    xq.pop(); //Note: Dont delete before popping...
    delete x; //Or keep it

    return 0;
}