gpt4 book ai didi

c++ - 在 C++ Vector 中存储从类模板继承的类

转载 作者:太空狗 更新时间:2023-10-29 20:54:26 25 4
gpt4 key购买 nike

我想存储派生自类模板的类 MyClassTemplate在一个 vector 中。

不幸的是,在 C++ 中无法定义 MyClassTemplate 的 vector 。没有指定它的参数(类似于 std::vector<MyClassTemplate<?,?>> myVector; )。

但是有一个可能的解决方案,即定义一个非模板化接口(interface)(只有纯虚函数的类)作为 vector 中项目的类型。该接口(interface)由类模板继承。在我的例子中,类模板只有使用模板参数的成员,所以似乎只有一个空接口(interface)才是适合我的 Vector 的项目类型。

这个问题还有其他(更好的)解决方案吗?

最佳答案

我从你的问题中了解到:

  • 你有一个模板类MyClassTemplate<class X, class Y> ;
  • 您已经知道每个模板实例化(例如 MyClassTemplate<A,B>MyClassTemplate<U,V> )都是不同的不相关类型;
  • 尽管如此,您还是希望将这种不相关的类型放在同一个 vector 中,以便能够使用公共(public)接口(interface)并以多态方式使用 vector 元素。

如何解决?

首先,您可以定义一个公共(public)的非模板祖先:

class MyCommonAncestor {
public:
virtual void common_operation1()=0;
virtual ~MyCommonAncestor() {}
};

template <class X, class Y>
class MyTemplateClass : public MyCommonAncestor {
X myx;
Y myY;
public:
void common_operation1() override;
X operation2(const Y& y);
};

不幸的是,这样做并不能真正让您使用 vector<MyCommonAncestor>因为这样的 vector 会持有 MyCommonAncestor只有对象(不能创建,因为它们在这里有一个纯虚函数),如果可以创建,它们将 slice您放入的派生对象(即它们有丢失 myXmyY 的风险)。

但是您可以创建一个指针 vector 。我在这里展示了一个简化的示例,使用原始指针;但实际上你最好使用 shared_ptr :

vector<MyCommonAncestor*> myVector; 
myVector.push_back(new MyTemplateClass<A,B>);
myVector.push_back(new MyTemplateClass<U,V>);

然后您可以根据 MyCommonAncestor 遍历元素并应用常用函数的界面。

挑战

当您要调用依赖于模板参数的函数时会遇到挑战(例如 operation2() )。显然,这些不能包含在共同祖先中,因为它们依赖于尚未定义的模板参数。

可能的解决方法:

  • 避免这些,并且仅通过通用操作(可以在模板中覆盖)间接调用此类函数
  • 在通用接口(interface)中使用参数抽象类型。通过指针或引用传递这些。稍后,对于 A 和 B 或 U 和 V,确保它们是从预期的抽象类型派生的。

Online demo (with smart pointers)

关于c++ - 在 C++ Vector 中存储从类模板继承的类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39105623/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com