前言

工作多年,主要接触三种语言C++、C#、JavaScript,分析一下它们类型转换的异同。

内容

下面介绍 C++、C#、JavaScript 的类型转换,多为引用他人博客和总结。C++、C#为强类型语言,JavaScript 为弱类型语言。弱类型语言和强类型语言 C++不是类型安全的,因为两个不同类型的指针之间可以强制转换。如果使用空类型指针或者在两个不同类型指针间做强制转换,很可能引发类型不安全的问题。 C#是类型安全的!CLR一个很重要的特性就是Type安全。CLR在任何时候都知道某个对象的类型。你可以通过GetType方法获得,由于该方法不是虚函数,因此不能被覆盖,也就是说返回的值是永远真实的。

C++

  1. C++中的四种cast转换
  2. C++类型转换

C++类型转换主要分为两种:隐式类型转换、显式类型转换(强制类型转换)。

隐式类型转换

隐式类型转换包括内置数据类型的转换自定义类型的转换,比如: 内置类型

int a = 1; 
int b = 2;
double = a + b;

自定义类型,实际上就是构造函数(复制构造函数、赋值运算符)。

class MyString
{
public:
    MyString(int n) {}; // 本意:预先分配n个字节给字符串
    MyString(const char* p) {}; // 用C风格的字符串p作为初始化值
    // ......
};

void main()
{
    MyString s1 = "China"; //OK 隐式转换,等价于MyString s1 = MyString(”China”)
    MyString s2(10); // OK 分配10个字节的空字符串
    MyString s3 = MyString(10); // OK 分配10个字节的空字符串

    MyString s4 = 10; // OK,编译通过。也是分配10个字节的空字符串
    MyString s5 = 'A'; // 编译通过。分配int('A')个字节的空字符串
    // s4 和s5 分别把一个int型和char型,隐式转换成了分配若干字节的空字符串,容易令人误解。
}
显式类型转换(强制类型转换)

四种类型:static_cast、dynamic_cast、const_cast、reinterpret_cast。 static_cast:static_cast是一个c++运算符,功能是把一个表达式转换为某种类型,但没有运行时类型检查来保证转换的安全性。

int a = 1;
double b = 2.0;
int* pa = &a;
double* pb = static_cast<double *>(pa); // 失败,不能转换
void* pv = static_cast<void *>(pa);
double* pb = static_cast<double *>(pv); // 成功

dynamic_cast:dynamic_cast是将一个基类对象指针(或引用)转换到继承类指针,dynamic_cast会根据基类指针是否真正指向继承类指针来做相应处理。

cosnt_cast:const_cast是一个基于C语言编程开发的运算方法,其主要作用是:修改类型的const或volatile属性。使用该运算方法可以返回一个指向非常量的指针(或引用)指向b1,就可以通过该指针(或引用)对它的数据成员任意改变。

reinterpret_cast:reinterpret_cast,是C++里的强制类型转换符。 reinterpret_cast < type-id > (expression) type-id 必须是一个指针、引用、算术类型、函数指针或者成员指针。它可以把一个指针转换成一个整数,也可以把一个整数转换成一个指针(先把一个指针转换成一个整数,再把该整数转换成原类型的指针,还可以得到原先的指针值)。

C#

C# 类型转换

类型转换从根本上说是类型铸造,或者说是把数据从一种类型转换为另一种类型。在 C# 中,类型铸造有两种形式: 隐式类型转换 - 这些转换是 C# 默认的以安全方式进行的转换, 不会导致数据丢失。例如,从小的整数类型转换为大的整数类型,从派生类转换为基类。 显式类型转换 - 显式类型转换,即强制类型转换。显式转换需要强制转换运算符,而且强制转换会造成数据丢失。

C# 能否像 C++ 那样 reinterpret_cast,可能不行:C#的类型安全

类型安全应该算是CLR最重要的特性之一了,在运行时,CLR总是知道一个对象的类型。在C#中可以调用GetType()来返回调用对象的类型,并且由于GetType()继承于System.Object对象,并且为非虚的方法,所以一个类型不可能通过重写此方法而伪装成另一种类型。

由于在开发的过程中,经常会需要将一个对象从一种类型转换为其他的类型,所以CLR允许将一个对象强制转换成它本身所引用的类型或派生其的基类型。一个对象向其父类的转换CLR认为是一种安全的隐式转换,不需要任何特殊的然而需要将一个对象转换为其派生类型时,则需要进行显示的转换,因为这样的转换可能在运行时失败。

JavaScript

作为一种脚本语言,JavaScript 变量都是 var,类型转换的意义也就有所不同了。JavaScript 类型转换

其它参考

C#是类型安全的c++ 类型安全