C ++标准指的是术语“动态类型”(C标准在类似的上下文中指的是“有效类型”),例如
如果某个程序试图通过以下某种类型之外的 glvalue 访问对象的存储值,则行为未定义:
- 对象的动态类型,
但是如何确定用malloc
分配的对象的动态类型?
例如:
void *p = malloc(sizeof(int));
int *pi = (int*)p;
pi
指向的对象的动态类型是int
吗?
答案 0 :(得分:8)
根据C ++规范:
动态类型:
< glvalue>由glvalue表达式表示的glvalue引用的最派生对象(1.8)的类型
malloc
的返回值是未初始化存储的块。在该存储中没有构造任何对象。因此它没有动态类型。
void*
不指向对象,只有对象具有动态类型。
您可以通过开始其生命周期在该存储中创建对象。但是在你这样做之前,它只是存储。
答案 1 :(得分:4)
在C中,有效类型仅在您访问对象时相关。然后在
确定memcpy
)void*
被转换为另一种指针类型(例如int*
),然后被解除引用。后者通常是malloc
ed对象发生的情况,如果将malloc
的返回值赋给指针类型。
答案 2 :(得分:3)
动态类型是描述基本上多态对象的正式术语,即具有至少一个virtual
函数的对象。因此,它是一个C ++术语,因为C没有virtual
的概念,例如。
但是如何使用malloc分配对象的动态类型 来确定
不是。 malloc
分配N
原始字节的内存并通过void*
返回 - 这是推断正确类型的工作。此外,此内存仅表示放置对象的区域,但在显式调用其构造函数之前,此对象将不会处于活动状态。 (再次,从C ++的角度来看)
pi指向的对象的动态类型是否为int?
不,因为在描述具有类类型的对象时,术语动态类型是有意义的。 int
不是也不是。
class Foo
{
//virtual ~Foo() = default;
virtual void f() {}
};
class Bar : public Foo
{
virtual void f() {}
};
// ...
Foo *ptr = new Bar();
此处Foo
是ptr
的静态类型,而Bar
是其动态类型。
答案 3 :(得分:3)
现状是malloc
不会创建对象。唯一的构造是new
表达式,定义,强制转换和赋值给变体成员。请参阅P0137R0以获取正确的措辞。
如果您想使用malloc
产生的存储空间,假设它已正确对齐(除非您使用扩展路线,情况就是这种情况),请调用新的位置:
auto p = malloc(sizeof(int));
int* i = new (p) int{0};
// i points to an object of type int, initialized to zero
因此,在C ++中使用malloc是没有用的,因为沼泽标准new
有效地将上述步骤合并为一个。
请参阅提问者相关问题中的@T.C.'s answer。
答案 4 :(得分:0)
根据C ++ 11标准中的1.3.7,
动态类型 由glvalue表达式表示的glvalue指向的最派生对象(1.8)的 glvalue 类型 [例如:如果指针(8.3.1)p的静态类型是“指向B类的指针”,则指向类的对象 D,源自B(第10条),表达式* p的动态类型是“D”。参考文献(8.3.2)被处理 与此类似。 - 结束例子]
示例
install_name_tool
class A {}
class B : public A {}
A *a = new B;
的“静态”类型为a
,而其动态类型为A *
。
引用不同类型的想法来防止像
这样的事情B *
可能导致未定义的行为。
class A{}
class B : public A {int x;}
class C : public A {int y;}
A *a = new B;
reinterpret_cast<C *>(a)->x;
没有指向一个对象,但动态和声明类型之间的区别仅对对象有意义。