派生对象数组的基指针 [英] Base pointer to array of derived objects

查看:115
本文介绍了派生对象数组的基指针的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

今天早些时候在这里问了问题以及大量类似的主题问题,我在这里从stadard的观点询问这个问题。

Following a question asked here earlier today and multitudes of similary themed questions, I'm here to ask about this problem from stadard's viewpoint.

struct Base
{
  int member;
};

struct Derived : Base
{
  int another_member;
};

int main()
{
  Base* p = new Derived[10]; // (1)
  p[1].member = 42; // (2)
  delete[] p; // (3)
}

根据标准是形式良好的,因为可以隐式转换 Dervied * (这是 new-expression 的结果)到 Base * (C ++ 11 draft,§4.10/ 3):

According to standard (1) is well-formed, because Dervied* (which is the result of new-expression) can be implicitly converted to Base* (C++11 draft, §4.10/3):


指向 cv D类型的指针的prvalue,其中D是类类型,可以是
转换为类型指向 cv B的prvalue ,其中B是D的基本
类(第10条)。如果B是不可访问的(第11条)或
模糊的(10.2)D的基类,则需要一个程序
转化不良。转换的结果是指向
的指针,它是派生类对象的基类子对象。空指针
值将转换为目标类型的空指针值。

A prvalue of type "pointer to cv D", where D is a class type, can be converted to a prvalue of type "pointer to cv B", where B is a base class (Clause 10) of D. If B is an inaccessible (Clause 11) or ambiguous (10.2) base class of D, a program that necessitates this conversion is ill-formed. The result of the conversion is a pointer to the base class subobject of the derived class object. The null pointer value is converted to the null pointer value of the destination type.

3)因为§5.3.5/ 3而导致未定义的行为:

(3) leads to undefined behaviour because of §5.3.5/3:


em> delete object ),如果要删除的
对象的静态类型与其动态类型不同,则静态
类型将是对象的动态类型的基类要删除
,静态类型应该有一个虚析构函数或
行为未定义。在第二种替代方案( delete array )中,如果要删除的对象的
动态类型与其静态类型不同,
的行为是未定义的。

In the first alternative (delete object), if the static type of the object to be deleted is different from its dynamic type, the static type shall be a base class of the dynamic type of the object to be deleted and the static type shall have a virtual destructor or the behavior is undefined. 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.

(2)根据标准合法,还是导致错误的程序或未定义的行为

Is (2) legal according to standard or does it lead to ill-formed program or undefined behaviour?

推荐答案

p>如果查看表达式 p [1] p Base 是完全定义的类型), 1 int ,所以根据ISO / IEC 14882:2003 5.2.1 [expr.sub]这个表达式是有效的并且等同于 *((p)+(1) )

If you look at the expression p[1], p is a Base* (Base is a completely-defined type) and 1 is an int, so according to ISO/IEC 14882:2003 5.2.1 [expr.sub] this expression is valid and identical to *((p)+(1)).

从5.7 [expr.add] / 5,当一个整数被添加到指针时,指针指向数组对象的一个​​元素,指针运算的结果也指向该数组对象的一个​​元素或一个超过数组末尾的元素。 p 但是,不指向数组对象的一个​​元素,它指向派生的基类子对象$ c> object。它是一个数组成员的 Derived 对象,而不是 Base 子对象。

From 5.7 [expr.add] / 5, when an integer is added to a pointer, the result is only well defined when the pointer points to an element of an array object and the result of the pointer arithmetic also points the an element of that array object or one past the end of the array. p, however, does not point to an element of an array object, it points at the base class sub-object of a Derived object. It is the Derived object that is an array member, not the Base sub-object.

注意,在5.7 / 4下,为了加法运算符的目的, Base 子对象可以被视为一个大小的数组一个,所以技术上你可以形成地址 p + 1 ,但作为一个过去的最后一个元素指针,它不指向 Base 对象并尝试读取或写入它将导致未定义的行为

Note that under 5.7 / 4, for the purposes of the addition operator, the Base sub-object can be treated as an array of size one, so technically you can form the address p + 1, but as a "one past the last element" pointer, it doesn't point at a Base object and attempting to read from or write to it will cause undefined behavior.

这篇关于派生对象数组的基指针的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆