C++11新特性:四种类型转换cast说明
阿里云国内75折 回扣 微信号:monov8 |
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6 |
目录
引言
C++11引入了四种类型转换接口它们分别是static_cast、const_cast、dynamic_cast、reinterpret_cast为什么要使用这四种转换呢
这里给出面向对象编程
和面向对象设计
的五个基本原则SOLID原则。
- Single Responsibility Principle单一职责原则
- Open Closed Principle开闭原则
- Liskov Substitution Principle里氏替换原则
- Law of Demeter迪米特法则
- Interface Segregation Principle接口隔离原则
- Dependence Inversion Principle依赖倒置原则
这里不详细叙述五个基本原则我们这里使用到的cast接口则和里氏替换原则
有关。
里氏替换原则 “派生类子类对象可以在程式中代替其基类超类对象。” 以上内容并非利斯科夫的原文而是译自罗伯特·马丁Robert Martin对原文的解读[1]。
1、static_cast
1.1 基本类型转换
1.2 类的上行转换安全
用于子类指针或引用转换为父类指针或引用。
#include <iostream>
using namespace std;
class Base
{
public:
Base() {};
virtual void Show() { cout << "This is Base class"; }
};
class Derived :public Base
{
public:
Derived() {};
void Show() { cout << "This is Derived class"; }
};
int main()
{
Derived* der = new Derived;
auto Derived = static_cast<Base*> (der);
//向上转换一直是安全的
Derived->Show();
system("pause");
}
输出结果为
This is Derived class
存在虚函数重载则父类的函数被隐藏不能使用。
由于使用方法会存在开销则一般使用下列方法进行向上转换。
class Base
{
public:
Base(){};
virtual void Show(){cout<<"This is Base class";}
};
class Derived:public Base
{
public:
Derived(){};
void Show(){cout<<"This is Derived class";}
};
int main()
{
Base *base ;
Derived *der = new Derived;
//向上转换总是安全
base = der;
base->Show();
system("pause");
}
1.3 类的下行转换不安全
将父类指针、引用转换为子类指针、引用但需要程序员自己检查因此这种转换方式也不存在额外的开销。
2、const_cast
2.1 改变常量属性
- 常量指针转化为非常量指针
- 常量引用转化为非常量引用
- 常量对象转化为非常量对象
3、dynamic_cast
该转换是运行时转换
其余都是编译时转换。主要用于安全的向下进行转换
。
3.1 类的上行转换安全
此处和static_cast是一样的不再过多叙述。
#include <iostream>
using namespace std;
class Base
{
public:
Base() {};
virtual void Show() { cout << "This is Base calss"; }
};
class Derived :public Base
{
public:
Derived() {};
void Show() { cout << "This is Derived class"; }
};
int main()
{
Derived* der = new Derived;
auto Derived = dynamic_cast<Base*> (der);
//向上转换一直是安全的
Derived->Show();
system("pause");
}
3.2 类的下行转换安全
因为有类型检查所以是安全的但类型检查需要运行时类型信息这个信息位于虚函数表中所以必须要有虚函数。
在dynamic_cast转换中分为两种情况。
- 1、当基类指针指向派生对象时能够安全转换。
- 2、基类指针指向基类时会做检查转换失败返回结果0。
#include <iostream>
using namespace std;
class Base
{
public:
Base() {};
virtual void Show() { cout << "This is Base class" << endl; }
};
class Derived :public Base
{
public:
Derived() {};
void Show() { cout << "This is Derived class" << endl; }
};
int main()
{
//第一种情况
Base* base = new Derived;
Derived* der = dynamic_cast<Derived*>(base);
//基类指针指向派生类对象时能够安全转换
der->Show();
//第二种情况
Base *base1 = new Base;
if (Derived* der1 = dynamic_cast<Derived*> (base1))
{
der1->Show();
}
else
{
cout << "error!";
}
delete(base);
delete(base1);
system("pause");
}
This is Derived class
error!
引用则和指针不同指针在C++11中存在空指针而引用不存在空引用会引发bad_cast
异常。
#include <iostream>
using namespace std;
class Base
{
public:
Base() {};
virtual void Show() { cout << "This is Base class" << endl; }
};
class Derived :public Base
{
public:
Derived() {};
void Show() { cout << "This is Derived class" << endl; }
};
int main()
{
//基类引用子类
Derived b;
Base& base1 = b;
Derived& der1 = dynamic_cast<Derived&>(base1);
der1.Show();
//基类引用基类
Base a;
Base& base2 = a;
try
{
Derived& der2 = dynamic_cast<Derived&>(base2);
}
catch(bad_cast)
{
cout << "bad_cast error!!" << endl;
}
system("pause");
}
This is Derived class
bad_cast error!!
4、reinterpret_cast
非关联类型的转换操作结果是一个指针到其他指针的二进制拷贝没有类型检查。