- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
#include <iostream>
using namespace std;
struct Base
{
virtual ~Base()
{
cout << "~Base(): " << b << endl;
}
int b = 1;
};
struct Derived : Base
{
~Derived() override
{
cout << "~Derived(): " << d << endl;
}
int d = 2;
};
int main()
{
Base* p = new Derived[4];
delete[] p;
}
输出如下:(Visual Studio 2015 with Clang 3.8)
~Base(): 1
~Base(): 2
~Base(): -2071674928
~Base(): 1
为什么多态性不适用于 C++ 中的数组?
最佳答案
给定,
Base* p = Derived[4];
C++11 标准制定
delete [] p;
是未定义的行为。
5.3.5 Delete
...
2 ... In the second alternative (delete array) if the dynamic type of the object to be deleted differs from its static type, the behavior is undefined.
从内存布局的角度来看,delete [] p;
的原因也是有道理的。将导致未定义的行为。
如果 sizeof(Derived)
是 N
, new Derived[4]
分配的内存类似于:
+--------+--------+--------+--------+
| N | N | N | N |
+--------+--------+--------+--------+
一般来说,sizeof(Base)
<= sizeof(Derived)
.在您的情况下,sizeof(Base)
< sizeof(Derived)
自从 Derived
有一个额外的成员变量。
使用时:
Base* p = new Derived[4];
你有:
p
|
V
+--------+--------+--------+--------+
| N | N | N | N |
+--------+--------+--------+--------+
p+1
指向自 sizeof(Base) < sizeof(Derived)
以来第一个对象中间的某个位置.
p+1
|
V
+--------+--------+--------+--------+
| N | N | N | N |
+--------+--------+--------+--------+
当在 p+1
上调用析构函数时,指针不指向对象的开始。因此,该程序表现出未定义行为的症状。
相关问题
由于 Base
的大小不同和 Derived
,您不能使用 p
遍历动态分配数组的元素.
for ( int i = 0; i < 4; ++i )
{
// Do something with p[i]
// will not work since p+i does not necessary point to an object
// boundary.
}
关于c++ - 为什么多态性不适用于 C++ 中的数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41113491/
我来自 Asp.Net 世界,试图理解 Angular State 的含义。 什么是 Angular 状态?它类似于Asp.Net中的ascx组件吗?是子页面吗?它类似于工作流程状态吗? 我听到很多人
我一直在寻找 3 态拨动开关,但运气不佳。 基本上我需要一个具有以下状态的开关: |开 |不适用 |关 | slider 默认从中间开始,一旦用户向左或向右滑动,就无法回到N/A(未回答)状态。 有人
我是一名优秀的程序员,十分优秀!