int *a,b; //代表指针a,整数b
int* a,b; //同上
int * a,b; //同上
指针本身是一个对象,它又可以指向另外一个对象。所以有两个定义:
执行对象copy的时候,顶层const不受影响,底层const的限制不能忽视,他们必须同时拥有同样的底层const资格或者两个对象的数据类型必须能够转换才行,一般来说非常量可以转换为常量,反之则不行。
const int &r = ci; //底层const,用于声明引用的都是底层const
const int* p = &value; //底层const,p指向的内容不变,
//此时可以 p = &other_value
//不可以 *p=123;
int * const q = &value; //顶层const,q指向的地址不变,地址里面的内容可以变
const int tmp = 42; //顶层const
//不可以 p = &other_value
//可以 *p=123;
const详解
c语言函数指针定义形式:返回类型 (*函数指针名称)(参数类型,参数类型,参数类型,…);
c++函数指针的定义形式:返回类型 (类名称::*函数成员名称)(参数类型,参数类型,参数类型,….);
函数类型由它的返回值和参数类型决定,与函数名无关
bool length_compare(const string &, const string &);
上述函数类型是:bool (const string &, const string &);
上述函数指针pf:bool (*pf)(const string &, const string &);
#include
using namespace std;
class test {
public:
int fun(int a, char c){
cout<<"this is fun call:"<
//如果是非类成员函数,在main函数中把对应的类去掉就行了
#include
using namespace std;
class test
{
public:
int fun(int a, char c)
{
cout<<"this is fun call:"<
#include
#include
float add(float a,float b)
{
printf("%f\n",a+b);
return a+b;
}
float minu(float a,float b)
{
printf("%f\n",a-b);
return a-b;
}
//用pfunType 来表示float(*)(float, float)
typedef float(*pfunType)(float, float);
int main()
{
pfunType p = &add;//定义函数指针变量
p(3.33, 2.22);
pfunType parry[2] = {&add, &minu};//定义函数指针数组
parry[1](3.33, 2.22);
using use_function = float(*)(float, float);
use_function temp = &add;
temp(123.11,555.1);
//函数指针作为参数可以定义为:void fun(pfunType p)
//函数指针作为返回值可以定义为:pfunType fun();
///原始函数指针数组为:float (*pfunArry[2])(float, float) = {&add, &minu};
//double k = pfunArry[0](3.33,2.22);// 调用方式
return 0;
}
避免使用强制类型转换,因为它干扰了编译器的正常的类型检查,reinterpret_cast尤为明显。static_cast、dynamic_cast也不应该频繁的使用,const_cast在重载函数的上下文中使用无可厚非。否则将错误百出。
reinterpret_cast作用:
IBM的C++指南、C++之父Bjarne Stroustrup的FAQ网页和MSDN的Visual C++也都指出:错误的使用reinterpret_cast很容易导致程序的不安全,只有将转换后的类型值转换回到其原始类型,这样才是正确使用reinterpret_cast方式。
int *ip;
char *pc = reinterpret_cast(ip);
我们必须牢记pc的真实对象是一个int类型,否则可能出现运行时的错误,例如:
string str(pc);
特许规则:
虽然不能隐式地将一个左值转换为右值引用,但是可以使用static_cast显示地将一个左值转换为一个右值引用。但是还是建议使用std::move(),使得去查找截断左值的代码变得容易。
一般性规则:
任何具有明确定义的类型转换,只要不包含底层的const,都可以使用static_cast
//i、j都是整形
double t = static(j) / i; //显示告诉编译器,我们不在乎精度的损失,减少警告
//我们必须确保转换后的类型就是指针所指的类型,否则出现未定义的错误
void *p = &d; //任何非常量对象地址都能存入void*
double *tp = static(p);
void *
任何非常量对象地址都能存入void*,以void*的视角来看内存空间,无法访问内存空间的内容,因为我们不知道是什么类型
使用形式:
其中type为一个类类型,并且通常情况下应该含有一个虚函数。
dynamic_cast(e); //e必须为一个有效指针
dynamic_cast(e); //e必须为一个左值
dynamic_cast(e); //e必须不是一个左值
在上面所有形式中,需要符合下面三个条件之一就能够转换成功:
否则将会转换失败,得到的结果将是0,并且抛出一个bad_cast的异常
const_cast只能改变运算对象的底层const,函数指针和成员函数指针不可用于 const_cast
const A *pca1 = new A; //A是一个类
A *pa2 = const_cast(pca1); //常量对象转换为非常量对象
const A &a1 = a0;
A a2 = const_cast(a1); //常量引用转为非常量引用
//下面两情况是未定义的情况
const char *pc;
char *p = const_cast(pc); //正确,但是通过p写值是未定义的行为,因为pc没有值
const int j = 3; // 声明 j 为 const
int* pj = const_cast(&j);
// *pj = 4; // 未定义行为
以后有空再学了,目前使用不到