具有不同模板的派生类对象的向量

Posted

技术标签:

【中文标题】具有不同模板的派生类对象的向量【英文标题】:Vector of objects of derived classes with different templates 【发布时间】:2014-08-25 10:26:53 【问题描述】:

考虑下面的基类:

template <typename T>
class food 
public:
    T quantity;
;

现在派生两个具有不同模板实例的类:

class cheese: public food<float> 

class chocolate: public food<int> 

在主函数中,我需要创建一个“食物”实例列表

int main () 
    vector<food*> bucket;

因为我不知道什么样的食物会被扔进桶里。但是,编译这段代码会产生错误:

error: missing template arguments before ‘*’ token

那么,我该怎么办呢?


现在我需要为派生类定义成员函数:

class cheese: public food<float> 
    float get_q() return quantity;

class chocolate: public food<int> 
    int get_q() return quantity;

问题是,如果我调用,编译器会说类 food 没有成员 get_q:

bucket.push_back(new cheese);
bucket.push_back(new chocolate);
bucket[0]->get_q();

在 main 中,即使我像这样更改 Quantity 界面

template <typename T>
class Quantity
public:
    T quantity;
    virtual T get_q() = 0;
;

看来编译器确实需要查看food 中定义的get_q(),但如果food 不是模板,那是不可能的,对吧?

对不起,我是一个新的 C++ 程序员,很多事情对我来说不是很清楚......

【问题讨论】:

模板参数是类型的一部分,所以它是不可能的。不过,您也许可以通过Boost Any 解决它。 是的,boost::any 是不错的选择。 感谢大家的解决方案。我真的需要在没有 Boost 库的情况下编写代码。在@RSahu 的解决方案中,似乎我必须在“food”类中虚拟定义派生类的所有成员函数,否则编译器会在编译时说该函数不是“food”的成员。跨度> 【参考方案1】:

food&lt;float&gt;food&lt;int&gt; 是不同的类型,它们不能像多态一样使用。

food* 没有命名类型,因为模板需要一个参数(这是编译器告诉你的)

您要么为所有food&lt;&gt; 类型提供一个公共基础(如果类型确实相关,您可能需要它),或者您将需要某种类型擦除包装器,例如boost::anyboost::variant


boost::any 示例:

#include <vector>
#include <boost/any.hpp>

template <typename T>
class food 
public:
    T quantity;
;

class cheese: public food<float> 
;

class cholocate: public food<int> 
;


int main()

    std::vector<boost::any> v;
    v.push_back(food<float>());
    v.push_back(food<int>());

【讨论】:

【参考方案2】:

您可以制作一个不是类模板的基类food,并制作一个捕获数量的类模板。

class food

;

template <typename T>
class Quantity
public:
    T quantity;
;

class cheese: public food, public Quantity<float> 
;

class cholocate: public food, public Quantity<int> 
;


int main()

    std::vector<food*> v;
    v.push_back(new cheese);
    v.push_back(new cholocate);

更新,以回应 OP 关于需要添加的评论

您可以添加get_quantity() 函数,例如:

class food

   public:
      virtual float get_quantity() const = 0;
;

class cheese: public food, public Quantity<float> 
   public:
      virtual float get_quantity() const
      
         return this->quantity;
      
;

class cholocate: public food, public Quantity<int> 
   public:
      virtual float get_quantity() const
      
         return this->quantity; // Implicit conversion to float.
      
;

【讨论】:

谢谢。假设我在奶酪中添加float get_quantity(),在巧克力中添加int get_quantity()。并使用 v[0]->get_quantity 在 main 中调用它们。编译器说class food doesn't have member get_quantity。但我不能将它添加到food 类,因为返回值被覆盖。有解决办法吗? @xna,请详细说明。你想添加什么?你想添加什么? 我详细阐述了这个问题。非常感谢。

以上是关于具有不同模板的派生类对象的向量的主要内容,如果未能解决你的问题,请参考以下文章

在基类类型的向量中保存的基对象和派生对象被切片

如何在另一个类的向量中调用派生类的析构函数

制作基类指针的向量并将派生类对象传递给它(多态)

创建基类对象的向量并将派生类对象存储在其中

从基类类型的向量访问派生类方法

试图将派生类对象地址分配给基类指针向量