最佳做法:将派生类的向量传递给基类向量上的方法
Best Practice: Passing a Vector of a Derived Class to a Method on a Vector of a Base Class
这是一个"最佳实践"问题:我可以想到几种方法,但我想知道社区认为哪一种是最好的。
我有一个方法如下:
void Foo(std::vector<BaseClass>& Objects) {...}
我现在想在Objects
上调用此方法,这是一个std::vector<DerivedClass>
。
例如,我可以考虑使用模板,或将 Sort 转换为接受std::vector<BaseClass*>
然后传递(Objects.begin(), Objects.end())
.
提前谢谢。
如果你需要动态多态性,你可以考虑 std::shared_ptr、std::unique_ptr 或包含指向(内部)多态类的指针的类。换句话说,'std::vector<BaseClass*>'是丑陋的。
如果使用静态多态性(模板),则排序也将成为模板。
最佳实践是接受一对迭代器,描述Foo应该操作的元素范围,可能提供方便的函数将范围转换为迭代器:
template <typename Iter>
void Foo(Iter first, Iter last) {...}
void Foo(std::vector<BaseClass>& Objects) {
Foo(begin(Objects), end(Objects));
}
void Foo(std::vector<DerivedClass>& Objects) {
Foo(begin(Objects), end(Objects));
}
// Or even a generic range adaptor,
template <typename Range>
void Foo(Range&& r) {
using std::begin; using std::end;
Foo(begin(r), end(r));
}
你需要一个模板。
绝对没有std::vector<Base>
和std::vector<Derived>
之间的关系,std::vector<Base*>
和std::vector<Derived*>
之间,或任何其他包装器之间。该语言将不允许你在没有不安全的类型转换的情况下替换这些东西,这只是未定义的行为。
如果你有一个函数接受std::vector<Base%>
(用任何东西替换%
),那么这就是你需要传递的。唯一的方法是创建一个正确类型的新向量并填充它。
或者你使它使功能更灵活,那就是通过使其成为模板。
如果你打算对容器的元素进行操作(例如对它们进行排序),我建议你遵循人们期望的约定:即标准库中使用的模式。
template<typename RandomAccessIterator>
void foo(RandomAccessIterator start, RandomAccessIterator end) { ... }
通过这种方式,您可以轻松用于您的任一类(Base
或Derived
),并且查看您的代码的其他人应该能够轻松分辨出它在做什么。
如果您尝试排序,您还可以提供模板的Predicate
版本,该版本允许您提供与默认值不同的排序方法(例如,如果要从大到小进行排序)。
- 如何通过派生类函数更改基类中的向量
- 如何在基类指针向量的元素上应用重载的多态函数
- 如何将子类作为函数的参数传递给期望基类,然后将该对象传递到指向这些抽象类对象的指针向量中?
- 如何访问基类向量中的子类变量?(对于实体组件系统)
- CRTP 与基类向量
- 基类到派生类的强制转换向量
- 创建基类指针的向量并将派生类对象传递给它(多态性)
- 有没有办法复制派生类指针的向量而不将其强制转换为基类?
- 无法将派生类存储在基类指针的向量中
- 基类类型向量中的派生结构
- 返回纯虚拟基类的向量的元素
- 基类中向量的干净实例化
- 带有基类指针的强制转换向量,指向子类
- 具有向量成员的基类<int>
- 将抽象派生类对象存储在基类向量中
- 如何从基类向量达到派生的类变量
- 如何为基类通用类型创建向量以使用具体类型元素
- 从基类对象的向量中获取特定派生类的对象
- 将子类添加到基类向量C++不起作用
- 如何将子类向量传递给需要基类向量的函数