C++ Primer笔记2_四种类型转换_异常机制

1.类型转换

命名的强制类型转换:

有static_cast、dynamic_cast、const_cast、reinterpret_cast

static_cast:

编译器隐式执行的任何类型转换都可以由static_cast完成

当一个较大的算术类型赋值给较小的类型时,可以用static_cast进行强制转换。

可以将void*指针转换为某一类型的指针

可以将基类指针强制转换为派生类指针,但是不安全。

无法将const转化为nonconst,这个只有const_cast才可以办得到

举例:

double d = static_cast<double>(j) / i;

void *p = &d;
double *dp = static_cast<double*>(p);

const_cast:

用来移除对象的常量性(cast away the constness), const_cast一般用于指针或者引用。

对于将常量对象转换为非常常量对象的行为,一旦去掉了const性质,编译器就不再阻止我们对该对象的写操作,结果是未定义的。

const char *pc;
char *p = const_cast<char*>(pc);//正确:但是通过p写值是未定义的行为;

char *p = static_cast<char *>(pc);//错误,static_cast不能转换掉const性质
static_cast<string>(pc);//正确,字符串字面值转换为string
const_cast<string>(pc);//错误,const_cast只改变常量属性

看下面一个例子:

#include <iostream>
using namespace std;

int main(void)
{
	const int a = 100;
	int *pA = const_cast<int *>(&a);
	*pA = 200;

	int &refA = const_cast<int &>(a);
	refA = 300;

//	int *pA1 = static_cast<int *>(&a);  Error 

	cout << "*pA:" << *pA << endl;//300
	cout << "refA:" << refA << endl;//300
	cout << "a:" << a << endl;//100

	return 0;
}

发现通过const_cast转换后,去除了const属性,然后对变量修改,运行时内存中的值是改变的,但最后打印修改后的值仍为原样。

下面是网上摘录的一段解释:

const只是告诉编译器不能修改而不是真正地不可修改,如果程序员不注意而去修改了它会报错,现在我们利用const_cast去除了常量性,然后通过指针和引用对其进行了修改,所以通过指针打印或者引用传参的时候就能看出其内存确实变化了,但为了保护val这个变量本来的const特性,所以每次我们使用val时,系统都将其替换成初始值100,确保了val还是“不可变”的

reinterpret_cast

常为运算对象的位模式提供较低层次上的重新解释。

举例:

int *pi;
char *pc = reinterpret_cast<char *>(pi);

我们必须牢记pc所指的真实对象是一个int而非字符,如果把pc当成字符指针在运行时可能出错。

如:string str(pc);

使用reinterpret_cast时非常危险的,一般避免使用。

dynamic_cast:

dynamic_cast主要用于类层次间的上行转换和下行转换,还可以用于类之间的交叉转换。

在类层次间进行上行转换时,dynamic_cast和static_cast的效果是一样的;

在进行下行转换时,dynamic_cast具有类型检查的功能,比static_cast更安全。

1.
安全的基类和子类之间转换。

2. 必须要有虚函数。

3. 相同基类不同子类之间的交叉转换。但结果是NULL。

例子:

#include <iostream>
using namespace std;

class A
{
	protected:
	int n;
	public:
		A(){n = 10;}
		virtual void getN(){}
};

class B : public A
{
	string name;
	public:
		B(){name = "SCOTT";}
		virtual void getN()
		{
			cout << "B: " << n << endl;
		}
		void printf()
		{
			cout << "name: " << name << endl;
		}
};

void Test(A * pA)
{
	B *pB1 = static_cast<B *>(pA);
	cout << "pB1: " << pB1 << endl;

	B *pB2 = dynamic_cast<B *>(pA);
	cout << "pB2: " << pB2 << endl;
}

int main()
{
	A *pA1 = new A;
	A *pA2 = new B;

	Test(pA1);//pB2为空指针 dynamic_cast将做类型检查,pB1虽然正确,但对其操作是不安全的,从这里可以看出static_cast没有dynamic安全
        Test(pA2);//OK 都是B类型对象

	return 0;
}

总结:

去const属性用const_cast。

基本类型转换用static_cast。

多态类之间的类型转换用daynamic_cast。

不同类型的指针类型转换用reinterpret_cast。

参考:

http://blog.csdn.net/ljz888666555/article/details/4541232

http://blog.csdn.net/jnu_simba/article/details/8868530

2.异常机制

try-catch-throw的使用:

#include <iostream>

using namespace std;

double fun(int a, int b)
{
	if(0 == b)
	{
		throw b;
	}
	return a/b;
}

int main()
{
	double a = 0.0;

	try
	{
		a = fun(2, 0);
	}
	catch(int)
	{
		cout << "Error: b is zero!" << endl;
	}
	catch(...)
	{
		cout << "Other error!" << endl;
	}
	cout << "a: " << a << endl;//still run after deal exception

	return 0;
}

自定义异常类:

#include <iostream>
using namespace std;

class MyException
{
	public:
		MyException(string name = "default name")
		{
			cout << "New Exception: " << name << endl;
			this->name = name;
		}
		~MyException()
		{
			cout << "Delete Exception: " << this->name << endl;
		}
		void myThrow()
		{
			throw MyException("Error");
		}
	private:
		string name;
};

int main()
{
	MyException m("Test");
	try
	{
		m.myThrow();
	}
	catch(...)
	{
		cout << "*****" << endl;
	}

	return 0;
}

运行结果:

New Exception: Test
New Exception: Error
*****
Delete Exception: Error
Delete Exception: Test

C++ Primer笔记2_四种类型转换_异常机制,布布扣,bubuko.com

时间: 2024-10-05 02:36:10

C++ Primer笔记2_四种类型转换_异常机制的相关文章

c++的四种类型转换

C++中四种类型转换方式 类型转换有c风格的,当然还有c++风格的.c风格的转换的格式很简单(TYPE)EXPRESSION,但是c风格的类型转换有不少的缺点,有的时候用c风格的转换是不合适的,因为它可以在任意类型之间转换,比如你可以把一个指向const对象的指针转换成指向非const对象的指针,把一个指向基类对象的指针转换成指向一个派生类对象的指针,这两种转换之间的差别是巨大的,但是传统的c语言风格的类型转换没有区分这些.还有一个缺点就是,c风格的转换不容易查找,他由一个括号加上一个标识符组成

C++引用,常量优化,四种类型转换符

变量引用是变量的别名,常量引用要加const,引用与被引用的东西是同一样. #include <string> #include <ctype.h> #include <vector> #include <iostream> #include <fstream> // using declarations states our intent to use these names from the namespace std using names

C++四种类型转换

C++有4种类型转换,reinterpret_cast, static_cast, dynamic_cast 和 const_cast reinterpret_cast reinterpret_cast 可以将一个指针转换为任意其它类型的指针或int,或反之亦可. 可以在互不相关的类之间进行指针转换,它只是简单地将一个指针的二进制数据复制到另一个指针,对指针指向的内容不做任何检查或转换. class A {}; class B {}; A * a = new A; B * b = reinter

[转]C++中四种类型转换符的总结

C++中四种类型转换符的总结 一.reinterpret_cast用法:reinpreter_cast<type-id> (expression)    reinterpret_cast操作符修改了操作数类型,但仅仅是重新解释了给出的对象的比特模型而没有进行二进制转换,即二进制值没有变.例如: int n=9; double d= reinterpret_cast< double > (n); 在进行计算以后, d 包含无用值. 这是因为 reinterpret_cast 仅仅是复

c++四种类型转换操作符简要总结

1.  static_cast<target>(expression) 可用于存在继承关系的类指针/引用之间的向上向下转换.执行向下转换时没有安全检查(区别于dynamic_cast),所以如果实际类型与目标类型不符合,编译虽然可以通过,但运行时的后果未定义. void*指针转换为实际的指针 其他基本类型的隐式转换以及反方向的转换,如:int <-> double 2.  dynamic_cast<target>(expression) 只能用于target为类指针或者

类型转换_异常处理机制

C++四种类型转换 static_cast C++静态类型转换,c语言隐式类型可以转换的,基本上都可以 //语法: type a = static_cast<type>(b); //b不为type类型 reinterpret_cast 指针类型不可以这么转化:指针需要强制类型转换: char* p1 = "hello"; int* p2 = NULL; p2 = reinterpret_cast<int*>(p1); dynamic_cast 用于继承中多态时候

C++四种类型转换方式。

类型转换有c风格的,当然还有c++风格的.c风格的转换的格式很简单(TYPE)EXPRESSION,但是c风格的类型转换有不少的缺点,有的时候用c风格的转换是不合适的,因为它可以在任意类型之间转换,比如你可以把一个指向const对象的指针转换成指向非const对象的指针,把一个指向基类对象的指针转换成指向一个派生类对象的指针,这两种转换之间的差别是巨大的,但是传统的c语言风格的类型转换没有区分这些.还有一个缺点就是,c风格的转换不容易查找,他由一个括号加上一个标识符组成,而这样的东西在c++程序

C++四种类型转换总结

const_cast,字面上理解就是去const属性. static_cast,命名上理解是静态类型转换.如int转换成char. dynamic_cast,命名上理解是动态类型转换.如子类和父类之间的多态类型转换. reinterpret_cast,仅仅重新解释类型,但没有进行二进制的转换. 4种类型转换的格式,如:TYPE B = static_cast(TYPE)(a). const_cast 去掉类型的const或volatile属性. struct SA { int i; }; con

C++中的四种类型转换运算符static_cast、dynamic_cast、const_cast和reinterpret_cast的使用

1.上一遍讲述了C语言的隐式类型转换和显示类型转换,C语言之所以增加强制类型转换,就是为了强调转换的风险性,但这种强调风险的方式是比较粗放了,粒度比较大,它并没有表明存在什么风险,风险程度如何. 2.为了使潜在风险更加细化,使问题追溯更加方便,使书写格式更加规范,C++ 对类型转换进行了分类,并新增了四个关键字来予以支持,它们分别是: 关键字 说明 static_cast 用于良性转换,一般不会导致意外发生,风险很低. const_cast 用于 const 与非 const.volatile