C++常量指针、指针常量以及强制类型转换

常量指针与指针常量

常量指针:指向常量的指针,const int p ;
指针常量:指针变量为常量,int * const p;
share_ptr < T > p;与T
p类似,都是非常量
const share_ptr < T > p;与T* const p类似,指针p是常量
share_ptr < const T > p;与const T* p类似,p指向的内容是常量
const share_ptr < const T > p;与const T* const p类似,都是常量

#include 
#include 

int main() 
{
	std::shared_ptr<int> A(new int(10));				//指针A以及A所指内容均为非常量
	const std::shared_ptr<int> B(new int(20));			//指针B为常量,B所指内容均为非常量
	std::shared_ptr<const int> C(new int(30));			//指针C为非常量,C所指内容为常量
	const std::shared_ptr<const int> D(new int(40));	//指针D以及D所指内容均为常量

	*A = 11;
	std::cout << "*A:" << *A << std::endl;
	A = B;
	std::cout << "*A:" << *A << std::endl;

	*B = 21;
	std::cout << "*B:" << *B << std::endl;
	//B = C;	//编译器报错,指针B为常量
	std::cout << "*B:" << *B << std::endl;

	//*C = 31;	//编译器报错,C所指内容为常量
	std::cout << "*C:" << *C << std::endl;
	C = D;
	std::cout << "*C:" << *C << std::endl;

	//*D = 41;	//编译器报错,指针D为常量
	std::cout << "*D:" << *D << std::endl;
	//D = A;	//编译器报错,D所指内容为常量
	std::cout << "*D:" << *D << std::endl;

	return 0;
}

强制类型转换

C++中新增了四个强制类型转换的关键字,分别为static_cast、const_cast、reinterpret_cast和dynamic_cast。

1、static_cast

用法:static_cast <类型说明符> (变量或表达式);它主要用于基本数据类型之间的转换、空指针转换成目标类型的空指针、任何类型的表达式转换为void类型以及类层次结构中基类和派生类之间指针或引用的转换,上行转换(把派生类的指针或引用转换成基类表示)是安全的,下行转换(把基类的指针或引用转换为派生类表示)没有动态类型检查,不安全。

2、const_cast

用法:const_cast<指针/引用> (变量或表达式);它主要用来修改类型的const或volatile属性,常量指针或引用被转换成非常量指针或引用,并且仍然指向原来的对象,常量对象被转换成非常量对象。

#include
using namespace std;

int main()
{
	int a = 10;
	const int * p = &a;
	int *q;
	q = const_cast<int *>(p);
	*q = 20;    //fine
	cout << "     " << a << "       " << *p << "       " << *q << endl;
	cout << "  " << &a << " " << p << " " << q << endl;
	cout << endl << endl;
	return 0;
}

运行结果:
在这里插入图片描述

#include
using namespace std;

int main()
{
	const int a = 10;
	const int * p = &a;
	int *q;
	q = const_cast<int *>(p);
	*q = 20;    //fine
	cout << a << " " << *p << " " << *q << endl;
	cout << &a << " " << p << " " << q << endl;
	return 0;
}

运行结果:
在这里插入图片描述
对比运行结果可知,当a为非常量时,q指针将a的内容改为了20,但当a为常量时,“*q=20”语句为未定义行为语句,a的值还是为10。

3、reinterpret_cast

用法:reinterpret_cast<指针/引用> (变量或表达式);它主要用来改变指针或引用的类型、将指针或引用转换为一个足够长度的整形、将整型转换为指针或引用类型。

4、dynamic_cast

用法:dynamic_cast<指针或引用> (变量或表达式);以上三种都是编译时完成的,dynamic_cast是运行时处理的,运行时要进行类型检查。dynamic_cast转换如果成功的话返回的是指向类的指针或引用,转换失败的话则会返回NULL。使用dynamic_cast进行类转换时基类中一定要有虚函数,否则编译不通过,因为类中存在虚函数,就说明它有想要让基类指针或引用指向派生类对象的情况,此时转换才有意义。对于类的转换,上行转换时dynamic_cast和static_cast的效果是一样的,下行转换时dynamic_cast具有类型检查的功能,比static_cast更安全。

#include
using namespace std;

class base
{
	public:
		virtual void vfun() { cout <<"base::vfun" << endl; }
		void fun() { cout << "base::fun" << endl; }
		void b() { cout << "base" << endl; }
};


class derived : public base
{
	public:
		void vfun() { cout << "derived::vfun" << endl; }	//重写(base类中vfun为虚函数)
		void fun() { cout << "derived::fun" << endl; }		//覆盖(base类中fun不为虚函数)
		void d() { cout << "derived" << endl; }
};

int main()
{
	base * instance_b;
	instance_b = new derived;//编译成功,可以使用基类指针指向派生类,派生类重写
	instance_b->vfun();
	instance_b->fun();
	instance_b->b();
	cout << endl;
	derived * instance_d;
	//instance_d = new base;//编译报错,只能使用基类指针指向派生类,并不能派生类指针指向基类
	//instance_d = static_cast(new base);	//不检测类型转换是否安全,基类可以没有虚函数
	instance_d = dynamic_cast<derived *>(new base);		//转换失败
	if (instance_d == nullptr)
		cout << "转换失败!" << endl;
	else
	{
		instance_d->vfun();
		instance_d->fun();
		instance_d->b();
		instance_d->d();
	}
	cout << endl;
	instance_d = dynamic_cast<derived *>(instance_b);	//运行时检测类型转换是否安全,基类必须存在虚函数
	if (instance_d == nullptr)
		cout << "转换失败!" << endl;
	else
	{
		instance_d->vfun();
		instance_d->fun();
		instance_d->b();
		instance_d->d();
	}
	delete instance_b;
	return 0;
}

运行结果:
C++常量指针、指针常量以及强制类型转换_第1张图片

你可能感兴趣的:(C++,c++,算法,c语言)