1、在C语言中类型装换分为隐式类型转换和显示类型装换
注意:隐式类型装换是编译器自己猜测开发者的意图,显示类型转换也叫作强制类型转换(编译器不能保证安全问题)
//隐式类型转换例子
#include
int main(int argc, char **argv)
{
double d = 100.1;
int i = d; // double转为int
char *str = "100ask.taobao.com";
int *p = str; // char *转为int * //编译会有警告
printf("i = %d, str = 0x%x, p = 0x%x\n", i, str, p); //以%x输出的时候编译器期望是一个unsigned int的变量,但是传入的不是的,所以编译器就会隐式转换
return 0;
}
//显式类型转换例子
#include
int main(int argc, char **argv)
{
double d = 100.1;
int i = d; // doubleתΪint
char *str = "100ask.taobao.com";
int *p = (int *)str; // char *תΪint *
printf("i = %d, str = 0x%x, p = 0x%x\n", i, (unsigned int)str, (unsigned int)p);
return 0;
}
2、C++提供了很多种类型装换
①动态转换、静态转换、重新解析转换(和C语言的显示转换一样)和对const类型转换
②动态类型转换:dynamic_cast
③静态类型转换:static_cast
④重新解析转换:reinterpert_cast
注意:const char *不能直接转化成int *,所以要是用const_cast()来去掉const属性
#include
int main(int argc, char **argv)
{
double d = 100.1;
int i = d; // double转换int
const char *str = "100ask.taobao.com";
char *str2 = const_cast<char *>(str); //去掉const属性
int *p = reinterpret_cast<int *>(str2); // char *转换int * //相当于C语言风格的用小括号强制类型转换
printf("i = %d, str = 0x%x, p = 0x%x\n", i, reinterpret_cast<unsigned int>(str), reinterpret_cast<unsigned int>(p));
return 0;
}
3、动态类型转换和静态类型转换
①dynamic_cast(&h)动态类型转换这个函数就是根据指针找到虚函数表找到类的信息
②动态新型转换只能够用在含有虚函数的类里面
注意:借用之前以人类为基类,然后有中国人和英国人继承人类作为基类
#include
#include
#include
using namespace std;
class Human {
private:
int a;
public:
virtual void eating(void) { cout<<"use hand to eat"<<endl; }
virtual ~Human() { cout<<"~Human()"<<endl; }
virtual Human* test(void) {cout<<"Human's test"<<endl; return this; }
};
class Englishman : public Human {
public:
void eating(void) { cout<<"use knife to eat"<<endl; }
virtual ~Englishman() { cout<<"~Englishman()"<<endl; }
virtual Englishman* test(void) {cout<<"Englishman's test"<<endl; return this; }
};
class Chinese : public Human {
public:
void eating(void) { cout<<"use chopsticks to eat"<<endl; }
virtual ~Chinese() { cout<<"~Chinese()"<<endl; }
virtual Chinese* test(void) {cout<<"Chinese's test"<<endl; return this; }
};
void test_eating(Human& h)
{
Englishman *pe;
Chinese *pc;
h.eating();
/* 想分辨这个"人"是英国人还是中国人? */
if (pe = dynamic_cast<Englishman *>(&h))
cout<<"This human is Englishman"<<endl;
if (pc = dynamic_cast<Chinese *>(&h))
cout<<"This human is Chinese"<<endl;
}
int main(int argc, char **argv)
{
Human h;
Englishman e;
Chinese c;
test_eating(h);
test_eating(e);
test_eating(c);
return 0;
}
4、动态类型转换能不能装换出他的父类呢
#include
#include
#include
using namespace std;
class Human {
private:
int a;
public:
virtual void eating(void) { cout<<"use hand to eat"<<endl; }
virtual ~Human() { cout<<"~Human()"<<endl; }
virtual Human* test(void) {cout<<"Human's test"<<endl; return this; }
};
class Englishman : public Human {
public:
void eating(void) { cout<<"use knife to eat"<<endl; }
virtual ~Englishman() { cout<<"~Englishman()"<<endl; }
virtual Englishman* test(void) {cout<<"Englishman's test"<<endl; return this; }
};
class Chinese : public Human {
public:
void eating(void) { cout<<"use chopsticks to eat"<<endl; }
virtual ~Chinese() { cout<<"~Chinese()"<<endl; }
virtual Chinese* test(void) {cout<<"Chinese's test"<<endl; return this; }
};
class Guangximan : public Chinese {
public:
void eating(void) { cout<<"use chopsticks to eat, I come from guangxi"<<endl; }
};
void test_eating(Human& h)
{
Englishman *pe;
Chinese *pc;
Guangximan *pg;
h.eating();
/* 想分辨这个"人"是英国人还是中国人? */
if (pe = dynamic_cast<Englishman *>(&h)) //动态类型转换指针
cout<<"This human is Englishman"<<endl;
if (pc = dynamic_cast<Chinese *>(&h)) //动态类型转换指针
cout<<"This human is Chinese"<<endl;
if (pg = dynamic_cast<Guangximan *>(&h)) //动态类型转换指针
cout<<"This human is Guangximan"<<endl;
}
int main(int argc, char **argv)
{
//Human h;
//Englishman e;
//Chinese c;
Guangximan g;
//test_eating(h);
//test_eating(e);
//test_eating(c);
test_eating(g);
return 0;
}
5、动态类型转换能不能转换引用?
①动态类型转换会根据类信息判断是不是属于类的对象,所以比强制类型转换要安全
注意:是不行的,会导致程序崩溃(引用必须指向一个实体),所以在动态类型转换过程中使用指针而不是使用引用
#include
#include
#include
using namespace std;
class Human {
private:
int a;
public:
virtual void eating(void) { cout<<"use hand to eat"<<endl; }
virtual ~Human() { cout<<"~Human()"<<endl; }
virtual Human* test(void) {cout<<"Human's test"<<endl; return this; }
};
class Englishman : public Human {
public:
void eating(void) { cout<<"use knife to eat"<<endl; }
virtual ~Englishman() { cout<<"~Englishman()"<<endl; }
virtual Englishman* test(void) {cout<<"Englishman's test"<<endl; return this; }
};
class Chinese : public Human {
public:
void eating(void) { cout<<"use chopsticks to eat"<<endl; }
virtual ~Chinese() { cout<<"~Chinese()"<<endl; }
virtual Chinese* test(void) {cout<<"Chinese's test"<<endl; return this; }
};
class Guangximan : public Chinese {
public:
void eating(void) { cout<<"use chopsticks to eat, I come from guangxi"<<endl; }
};
void test_eating(Human& h)
{
#if 1
//Englishman& pe = dynamic_cast(h); //动态类型转换引用
Chinese& pc = dynamic_cast<Chinese&>(h); //动态类型转换引用
Guangximan& pg = dynamic_cast<Guangximan&>(h); //动态类型转换引用
h.eating();
}
int main(int argc, char **argv)
{
//Human h;
//Englishman e;
//Chinese c;
Guangximan g;
//test_eating(h);
//test_eating(e);
//test_eating(c);
test_eating(g);
return 0;
}
6、上下行转换
#include
#include
#include
using namespace std;
class Human {
private:
int a;
public:
virtual void eating(void) { cout<<"use hand to eat"<<endl; }
virtual ~Human() { cout<<"~Human()"<<endl; }
virtual Human* test(void) {cout<<"Human's test"<<endl; return this; }
};
class Englishman : public Human {
public:
void eating(void) { cout<<"use knife to eat"<<endl; }
virtual ~Englishman() { cout<<"~Englishman()"<<endl; }
virtual Englishman* test(void) {cout<<"Englishman's test"<<endl; return this; }
};
class Chinese : public Human {
public:
void eating(void) { cout<<"use chopsticks to eat"<<endl; }
virtual ~Chinese() { cout<<"~Chinese()"<<endl; }
virtual Chinese* test(void) {cout<<"Chinese's test"<<endl; return this; }
};
class Guangximan : public Chinese {
public:
void eating(void) { cout<<"use chopsticks to eat, I come from guangxi"<<endl; }
};
void test_eating(Human& h)
{
#if 1
//Englishman& pe = dynamic_cast(h); //动态类型转换引用
Chinese& pc = dynamic_cast<Chinese&>(h); //动态类型转换引用
Guangximan& pg = dynamic_cast<Guangximan&>(h); //动态类型转换引用
#else
Englishman& pe = reinterpret_cast<Englishman&>(h); //强制类型转换
Chinese& pc = reinterpret_cast<Chinese&>(h); //强制类型转换
Guangximan& pg = reinterpret_cast<Guangximan&>(h); //强制类型转换
#endif
h.eating();
}
int main(int argc, char **argv)
{
Human h;
//Englishman e;
//Chinese c;
Guangximan g;
Englishman *pe;
pe = static_cast<Englishman *>(&h); //下行转换,这个人的类转换成英国人的时候有安全隐患,static_cast是检查不出来的
//Englishman *pe2 = static_cast(&g); //广西人不能够转换成英国人(他们之间没有关系啊),static_cast可以检查出来
Chinese *pc = static_cast<Chinese *>(&g); //上行转换,广西人可以上行转换成中国人,因为他们之间有继承关系
return 0;
}