【问题标题】:Polymorphism with array in C++ 11C ++ 11中的数组多态性
【发布时间】:2019-12-18 04:13:30
【问题描述】:

我很困惑。代码末尾一定要delete s[]吗?

将派生类对象分配给基类类型的数组(固定大小)的正确方法是什么?

int main () {

    Shape *s[2];
    s[0] = new Circle(...);
    s[1] = new Rectangle(...);
    // etc

    delete s[] // Do you have to delete ?
}

【问题讨论】:

  • delete s[] 不是有效的语法。它不会编译。所以当然你不应该把它添加到你的代码中。
  • 这段代码中有两次new的调用,所以应该有两次delete的调用。由于您在s[0]s[1] 中存储了指向已分配内存的指针,因此您应该删除s[0]s[1],如delete s[0]; delete s[1];。或者类似for (int i = 0; i < 2; ++i) delete s[i]; 更好的是,使用智能指针(例如std::unique_ptr)代替原始指针,并可能使用标准容器(例如std::vector)代替数组。
  • Object destruction in C++的可能重复
  • @IgorTandetnik 谢谢。因此,如果有Shape *s[10] 但只有 s[0] 和 s[1],当使用 for 循环删除时,我是否会循环直到 10 喜欢。 for (int i = 0; i < 10; ++i) delete s[i];

标签: arrays c++11 pointers polymorphism delete-operator


【解决方案1】:

通常需要手动删除,但如果在int main,则不需要,因为操作系统会在程序完成后自动释放你分配的所有内存。

但是,只有当您使用 new Shape[n] 语法分配内存时,这才是正确的。使用您的语法,您不需要释放数组。

delete[] 不会释放底层指针,只是释放指针数组。您还需要循环并手动删除内容。

【讨论】:

  • 在我看来,这是一个危险的习惯:不对使用new 创建的任何对象调用delete 意味着不会调用该对象的析构函数,请参见,例如。 stackoverflow.com/questions/677812/….
【解决方案2】:

行为取决于您分配实际内存的位置。如果您在堆栈上分配数组,则不应为数组本身释放内存,但您仍然必须遍历所有指针以释放内存:

    Shape* s[2];
    s[0] = new Circle;
    s[1] = new Rectangle;
    for (int i = 0; i < 2; ++i)
    {
        delete s[i];
    }

或者如果你真的因为某些原因想在堆中分配内存,你可以直接在堆上创建一个指针数组,所以不要忘记释放数组本身的内存:

    Shape **s = new Shape*[2];
    s[0] = new Circle;
    s[1] = new Rectangle;
    for (int i = 0; i < 2; ++i)
    {
        delete s[i];
    }
    delete[] s;

【讨论】:

    猜你喜欢
    • 2017-11-02
    • 1970-01-01
    • 2012-05-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多