在C语言中,你可以隐式地将*void 转换为*T。这是不安全的。考虑一下:
#include<stdio.h>
int main()
{
char i = 0;
char j = 0;
char* p = &i;
void* q = p;
int* pp = q; /* 不安全的,在C 中可以,C++不行 */
printf("%d %d\n",i,j);
*pp = -1; /* 覆盖了从 i开始的内存 */
printf("%d %d\n",i,j);
}
使用一个并不指向T 类型的 T*将是一场灾难。因此,在 C++中,如果从一个void*得到一
个 T*,你必须进行显式转换。举例来说,要得到上列程序的这个令人别扭的效果,你可以
这样写:
int* pp = (int*)q;
或者使用一个新的类型造型,以使这种没有检查的类型转换操作变得更加清晰:
int* pp = static_cast<int*>(q);
造型被最好地避免了。
在 C 语言中,这种不安全的转换最常见的应用之一,是将 malloc()的结果赋予一个合适
的指针。例如:
int* p = malloc(sizeof(int));
在C++中,使用类型安全的 new操作符:
int* p = new int;
附带地,new 操作符还提供了胜过malloc()的新特性:
new 不会偶然分配错误的内存数量;
new 会隐式地检查内存耗尽情况,而且
new 提供了初始化。
举例:
typedef std::complex<double> cmplx;
/* C 风格: */
cmplx* p = (cmplx*)malloc(sizeof(int)); /* 错误:类型不正确 */
/* 忘记测试p==0 */
if (*p == 7) { /* ... */ } /* 糟糕,忘记了初始化*p */
// C++风格:
cmplx* q = new cmplx(1,2); // 如果内存耗尽,将抛出一个 bad_alloc 异
常
if (*q == 7) { /* ... */ }