使用基类而不是基指针来处理派生类

meg*_*uli 4 c++ inheritance

我有一个这样的基础抽象类;

class X {
public:
    virtual ~X(){}
    virtual doSomething() = 0;
};
Run Code Online (Sandbox Code Playgroud)

然后我用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()
    }
}
Run Code Online (Sandbox Code Playgroud)

这会按预期调用各自的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()
    }
}
Run Code Online (Sandbox Code Playgroud)

因此,当我离开主要时,将自动调用析构函数.我知道我不能创建一个抽象类的成员,但使用指针来实现这一切似乎很奇怪.当然必须有一种方法可以在没有指针和新删除的情况下执行此操作.如果有人向我展示了最佳实践,那将会很棒.

Ker*_* SB 5

您想使用适当的智能指针:

std::vector<std::unique_ptr<X>> v;

v.push_back(std::make_unique<Y>());
v.push_back(std::make_unique<Z>());

// all done
Run Code Online (Sandbox Code Playgroud)

(当然还有动态分配,因为在没有运行时间接的情况下你无法管理无限数量的无约束类型,但你不应该手动考虑任何动态管理.类型系统可以为你完成所有的工作.)

  • @meguli:朋友之间的交易怎么样:你花了接下来的24小时搜索互联网,特别是Stack Overflow,以获取'unique_ptr`的解释和用法示例.然后,如果在那之后您仍然不确定,请告诉我,我会写出更多细节.怎么样? (4认同)
  • @JohnZwinck:是的. (2认同)
  • @JohnZwinck:你应该有!(例如,通过将"if"改为"why".)答案是因为a)你永远不想在你的代码中说'new`,b)你希望你的代码在子表达式方面是正确的,并且c)因为推-back(增加值)在语义上更简单,并且比更具侵略性的安置(通过显式构造函数直接初始化)更好地分割职责. (2认同)