访问模板类对象向量中的对象

Posted

技术标签:

【中文标题】访问模板类对象向量中的对象【英文标题】:accessing objects in a vector of template class objects 【发布时间】:2019-12-04 14:13:37 【问题描述】:

通过实现这个答案,我有一个模板类的各种对象的向量:https://***.com/a/36588158/5088457

我正在使用 qt 进行开发。但是我在投射/访问这些对象时遇到了麻烦。所以我的问题是,当我不知道模板类型时,如何获取 shared_ptr 后面的对象?正如您在下面的代码 sn-p 中看到的,它是关于从向量 As 中获取一个 AImpl 对象。谢谢!

我认为作者的代码 sn-p 是一个很好的最小示例:

class A;

template <class T>
class AImpl : public A
public:
    T obj;
    AImpl(T _obj):obj(_obj)
    ~AImpl()
        cout << "Deleting " << obj << endl;
    
;

int main(int argc, char** argv)

    AImpl <string>* a1 = new AImpl <string> ("string1234");
    AImpl <int>* a2 = new AImpl <int> (1234);
    AImpl <double>* a3 = new AImpl <double> (1.234);
    vector <shared_ptr<A>> As;
    As.push_back(shared_ptr<A>(a1));
    As.push_back(shared_ptr<A>(a2));
    As.push_back(shared_ptr<A>(a3));





【问题讨论】:

类型擦除不是什么神奇的武器。是的,您将所有这些对象放入一个向量中——但是为什么呢?你真正想要完成什么? C++ 是一种强类型语言,所以要对你的对象做任何有用的事情,你需要以某种方式再次记住/找出正确的类型。如果您没有办法做到这一点,那么类型擦除可能不是正确的解决方案。 换句话说:你告诉我们你用了一把锤子,钉子现在卡在木头上,你想把它弄回来。有很多方法可以使钉子重新拔出。其中一些速度很慢。其中一些涉及破坏木材。但是我们不能给你一个有用的答案,因为我们不知道你为什么把钉子放在那里,又把它们弄出来的目的是什么。也许您实际上并不需要锤子和木头?这看起来像XY problem,所以我建议你首先描述一下你真正想要完成的事情。 【参考方案1】:

所以我的问题是,当我不知道模板类型时,如何获取 shared_ptr 后面的对象?

答案是你不能,分别是你不能Aimpl之外,这是唯一存放对象类型的地方是已知的。

类型擦除主要用于所有类型擦除对象共享某个公共接口时。例如,在您的情况下,您可以将intstd::stringdouble 的内容输入到输出流中。要通过 pointer-to-base A 执行此操作,您需要使用 virtual 函数:

class A

  public: virtual void print() const = 0;
;

template <class T>
class AImpl : public A

  T obj;
public:      
  AImpl(T _obj) : obj(_obj)        
  ~AImpl()  cout << "Deleting " << obj << endl; 

  virtual void print() const override
  
    cout << obj << endl;
  
;

然后,您可以打印出存储在As 中的所有类型擦除对象的值,如下所示:

for (const auto ptr& : As) As->print();

【讨论】:

感谢它的工作!我正在使用这些类型的已擦除对象,因为它们共享一个通用接口。我的数据是某种键值对,其中的值可以是原始类型,甚至是复杂类型。

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

传递派生模板类的向量

类模板特化中的成员变量别名

C ++跨类访问基对象向量中的派生对象的引用

如何在 C++ 中访问类对象向量中的对象?

面向对象——对象的创建和使用

类与模板注意事项