使用基类而不是基指针来处理派生类
Using base class rather than base pointer to work on derived class
我有一个这样的抽象基类;
class X {
public:
virtual ~X(){}
virtual doSomething() = 0;
};
然后我用两个类来实现这一点,比如Y、Z等,每个类都有自己的构造函数、析构函数和doSomething实现。在我的主要职能中,我做到了;
int main(){
std::vector<X *> v;
X *x1 = new Y();
X *x2 = new Z();
v.push_back(x1);
v.push_back(x2);
for(auto p : v){
p->doSomething()
}
}
这将按预期调用各自的doSomething实现。但我的问题是,我使用指向抽象类的指针,通过基类来操纵派生类的层次结构。这迫使我使用new在堆上创建实例,之后我必须手动删除它们。有没有办法做这样的事情;
int main(){
std::vector<X> v;
Y x1();
Z x2();
v.push_back(x1);
v.push_back(x2);
for(auto p : v){
p.doSomething()
}
}
这样,当我离开main时,析构函数就会被自动调用。我知道我不能创建抽象类的成员,但使用指针来实现这一切似乎很奇怪。当然,必须有一种方法来做到这一点,而不需要指针和新的删除。如果有人向我展示最佳实践,那就太好了。
您想要使用一个合适的智能指针:
std::vector<std::unique_ptr<X>> v;
v.push_back(std::make_unique<Y>());
v.push_back(std::make_unique<Z>());
// all done
(当然仍然有动态分配,因为如果没有运行时间接性,你就无法管理无限数量的无约束类型,但你永远不应该手动思考任何动态管理。类型系统可以为你做所有的工作。)
尽管Kerrek SB给出了很好的答案,但OP要求提供一个无new
的解决方案,值得再添加一个答案
您可以使用std::reference_wrapper
它遵循一个最小的工作示例:
#include<vector>
#include<functional>
#include<iostream>
class X {
public:
virtual ~X(){}
virtual void doSomething() = 0;
};
class Y: public X {
void doSomething() override {
std::cout << "Y" << std::endl;
}
};
class Z: public X {
void doSomething() override {
std::cout << "Z" << std::endl;
}
};
int main(){
std::vector<std::reference_wrapper<X>> v;
Y x1{};
Z x2{};
v.emplace_back(x1);
v.emplace_back(x2)
for(X &p : v){
p.doSomething();
}
}
注意,在这种情况下,必须保证存储对象的生存期超过向量的生存期
如果您计划使用std::unique_ptr
s,则不会出现此问题,正如Kerrek SB的另一个答案所建议的那样。
相关文章:
- 在C#中处理C++指针而不使用unsafe的最佳方法
- 在自定义 std::vector-like 容器中处理指针和非指针模板类型的最佳方法是什么?
- 如何在 c++ 中处理 LinkedList 的指针
- C++在一个映射中存储不同的指针类型(并处理销毁)
- 处理从列表中删除指向对象的指针的"healthy"方法是什么?
- C 与 C++,处理 void** 指针
- OpenCV如何处理Mat作为指针来加速代码
- 在C++中使用指针进行字符串处理
- delete运算符如何处理c中的指针
- 指针向量的向量的处理元素
- 在同时处理基类的多个指针时如何处理多态性?
- 处理 pybind11 中的不透明指针
- 为什么Arduino对Mega 2560和ESP8266的角色指针处理有两种不同的行为
- 识别指针处理方式中的错误
- 使用指针处理结构的动态表
- 使用指针指向指针处理 C 中的结构数组
- 使用指针处理字符串
- C++指针处理
- ARM体系结构中的指针处理和Valgrind方法
- 如何在C++中通过指针处理3d数组