在成员数据中使用模板参数的模板类的基类指针

Posted

技术标签:

【中文标题】在成员数据中使用模板参数的模板类的基类指针【英文标题】:Base class pointer for a template class that uses template parameter in member data 【发布时间】:2017-04-29 10:44:01 【问题描述】:

对于下面的模板类

template <class T> class Arbitrary 
protected:
    vector<T> ObjectArray;
public:
    Arbitrary()   
;

我希望能够拥有一个基类指针向量,我知道我需要使用接口类但我无法让它工作,任何建议将不胜感激。

【问题讨论】:

“无法正常工作”是什么意思?您到底尝试过做什么,发生了什么,遇到了什么错误,... 我不知道该怎么做,我知道我最终想写 vector name; 因为Arbitrary 是一个模板类型,所以你只能执行vector&lt;Arbitrary&lt;int&gt;*&gt; name; 之类的操作,或者使用std::anystd::variant 之类的操作 【参考方案1】:

[..]我最终想写vector&lt;Arbitrary*&gt; name;

Arbitrary 是一个模板,而不是一个类型。要从中“获取”一个类型,您需要将其“应用”到另一种类型(如int)。这会给你Arbitrary&lt;int&gt; 作为“结果”类型。这个过程称为模板实例化

如果你想要一个包含任何可能类型的对象的向量,这些对象可能已经从模板Arbitrary 实例化,那么你需要给它们一个通用类型(这样每个对象“都是”该通用类型的对象) .这是因为std::vector 只存储单一类型的对象。

要让对象“行为”(在某种类型的意义上)不同,即使它们“具有”一个通用类型,您需要使它们(或者更确切地说是它们的通用类型)多态 .这是通过给公共类型一些virtual 函数来完成的。 (而且由于您想通过公共类型公开的“接口”删除/破坏对象,您需要使析构函数成为虚拟!)

struct ArbitraryBase 
  // Add "common interface" functions here, as virtual
  virtual ~ArbitraryBase() = 0; // pure virtual to avoid creating objects
;
inline ArbitraryBase​::~ArbitraryBase() 

template<typename T>
struct Arbitrary : ArbitraryBase 
  // whatever
;

现在,要真正能够使用该多态属性而不是成为对象切片的受害者,您需要使用引用或指针语义:

std::vector<ArbitraryBase *> objects;

如果objects 向量应该拥有对象的所有权,您应该考虑使用智能指针,而不是原始指针,例如std::unique_ptr&lt;ArbitraryBase&gt;,否则使用std::reference_wrapper&lt;ArbitraryBase&gt;,以防对象的生命周期得到可靠处理用别的东西。

但如果你不在ArbitraryBase 中添加任何通用接口(更多虚拟成员函数),那么你基本上是在重新发明std::any / boost::any。所以最好改用那些经过良好测试的实现。

【讨论】:

谢谢,我正在使用更多的虚拟成员函数。如何处理属于 T 的函数的虚成员函数,即 virtual void function(T) 你不能有这样的成员函数。 T 对从 Arbitrary 实例化的所有类型来说都是“通用的”。实际上 - 假设没有模板专业化 - T 是所有这些类型的不同之处。

以上是关于在成员数据中使用模板参数的模板类的基类指针的主要内容,如果未能解决你的问题,请参考以下文章

派生类中隐藏的基类模板成员函数,尽管参数列表不同

基类的函数指针指向子类的成员函数?

带有接受派生类参数的基类参数的成员函数指针

在派生类中专门化模板成员

DLL-导出模板基类的静态成员

包含指向派生模板类的基类指针的类的赋值运算符和复制构造函数