C++11 向量包含 2 个不同的子类,但不能同时进行
C++11 vector holding 2 different subclasses, but not at the same time
>假设我有一个基类Base
,两个子类A
和B
,后者本身有一个子类C
。
我想通过设计强制std::vector
可以容纳任一类型的对象(包括C
等子类(,但一次只能容纳一种类型——也就是说,我有一个A
s 的向量,或者一个B
s 和C
s 的向量。
是否可以在 C++11 中拥有这个(当然,我可以在向向量添加元素时强制执行此约束,但我想知道我是否可以通过巧妙的设计来防止这种情况(?如何构建类层次结构来获得此值?
提前感谢您的帮助!
R.
boost::variant< std::vector<A>, std::vector<boost::variant<B,C>> >
描述了你的结构。
C++17 年,将boost::
替换为std::
. 两者非常相似,但不完全相同。
如果你不能使用boost
,你基本上必须编写自己的variant
。
使用有点尴尬,但您的类型限制也是如此。 在 C++14 中使用自动 lambdas(我相信这会增强变体访问者的支持(变得更加容易。
在 C++14/17 中,您可能会执行以下操作(伪代码(
template<class F, class T, class=std::enable_if_t<!is_variant<T>{}>>
decltype(auto) visit( F&& f, T&& t ) {
return std::forward<F>(f)(std::forward<T>(t));
}
my_special_vec v;
visit( [&](auto&& v){
for (auto&& e:v) {
Base* b = visit( [&](auto&& e){
e.do_operation();
return std::addressof(e);
}, decltype(e)(e));
b->do_virtual_operation();
}
}, v );
它应该在向量包含的A
、B
或C
中的任何一个上非虚拟地调用e.do_operation()
,然后在实例上调用do_virtual_operation()
作为Base
。
这是更简单的 C++14 版本。 C++11版本在函数对象和其他混乱中变得尴尬。
std::vector<T>
只能容纳一种类型的对象:T
。它永远不能保存派生对象,也不能在运行时更改类型。
通过使用间接寻址,可以单独分配对象,而是在向量中存储指向基类的指针。这允许向量指向派生对象,但不会阻止同时混合不同类型的对象。
您可以使用标记的联合实现您所描述的内容。C++11 标准库没有标记的联合类型(std::variant
将在 C++17 中引入(,因此您需要自己实现它(或者您当然可以像往常一样使用第三方实现(。标记联合允许您列出可以存储的类型,并且一次有一个类型处于活动状态。所以你可以有一个变体std::vector<A>
,std::vector<A>
和std::vector<C>
.
也就是说,您还没有描述为什么需要它,更好的设计可能是使用几个单独的向量。
- 是否可以将函数导入命名空间,但不能导出它?
- std::unique_ptr 在 GCC 中工作,但不能在 Visual Studio 中编译
- 可以访问一个类中的播放器结构,但不能访问另一个类中的播放器结构
- C++11 向量包含 2 个不同的子类,但不能同时进行
- C++为什么 int 变量可以声明为类的私有数据成员,但不能声明为字符串变量
- 继承比较运算符,但不能将派生类彼此进行比较
- 我自己的C++框架(类似MFC),我可以创建子窗口,但不能在WM_create时创建编辑框
- 将参数类为可选函数指针,但不能识别为函数
- 必须在类成员函数的返回类型中提供更具体的类型,但不能提供参数类型
- 为什么我可以在Qt 5.5.1中使用QSerialPort*作为临时变量,但不能用作类的成员?
- OOP设计-受保护的成员不在自己的类中使用,但仅在子类中使用
- 设置为实例的静态值在从静态方法设置时有效,但不能从类内的静态方法设置
- 是否可以从模板基类继承,但不能使派生类也成为模板
- C++ 为什么我可以初始化静态常量字符,但不能初始化类定义中的静态常量双精度
- 告诉 mstest 忽略基类中的测试方法,但不忽略子类中的测试方法
- c++声明向量数组以获取类,但不能访问成员变量
- C++抽象类的问题(我可以用Java做,但不能用C++!)
- 创建了我自己的向量类.可以重载流运算符,但不能按值c++打印
- c++是否可以继承一个类,但不能继承该类继承的内容?(qt)
- 模板基类可以存储指向派生但不能存储对象的指针 - 为什么