一、指针简概
(一)指针定义
指针(pointer)是“指向(point to)”另外一种类型的复合类型。与引用类似,指针也实现了对其他对象的间接访问。然而指针与引用相比又有很多不同点。其一,指针本身就是一个对象,允许对指针赋值和拷贝,而且在指针的生命周期内它可以先后指向几个不同的对象。其二,指针无须在定义时赋初值。和其他内置类型一样,在块作用域内定义的指针如果没有被初始化,也将拥有一个不确定的值(通常为避免“无效指针/野指针”的出现,会将指针初始化为空值(如nullptr、NULL、0))[1]。
补充说明:
1. 指针存放某个对象的地址,想要获取该地址,需要使用取地址符(操作符&);
2. 如果指针指向了一个对象,则允许使用解引用符(操作符*)来访问该对象。
(二)空类型指针(Void *ptr)
空类型指针(泛型指针或void*)是C++提供的一种特殊的指针类型,空类型指针可以指向任意非常量数据类型,空类型指针表明相关的值是个地址,但该地址的对象类型未知。空类型指针常被用于“对象的确切类型未知”、“在特定环境下对象的类型会发生变化”或者“需要持有地址值(比较多个地址)”的情况。
注意事项:
1. 不能够直接操作空类型指针所指向的对象,只能传送该地址值或将它与其他地址值作比较。由于没有类型信息可用来指导编译器解释底层的位模式,void*类型指针不能直接被解除引用(若需要操作空类型指针所指向的对象,必须显式转换为对应类型指针);
2. 在显式转换(强制类型转换,即包含static_cast、dynamic_cast、const_cast和reinterpret_cast强制类型转换操作符)中,任何非const数据类型的指针都可以被赋值给void*类型的指针(const数据类型的指针对应const void*)。相反,void*类型的指针必须先被转换成某种特定类型的指针,才能够被赋值给某种特定类型的指针。
(三)函数指针
函数指针指向的是函数而非对象。和其他指针一样,函数指针指向某种特定类型。函数的类型由它的返回类型和形参类型共同决定,与函数名无关。
bool (*ptr)(const string &,const string &) = nullptr;
上述函数指针初始化示例中,ptr为函数指针,该函数指针类型为bool (*)(const string &,const string &)。ptr指向一个函数,该函数的参数是两个const string的引用,返回值是bool类型。
函数指针使用基本说明(p222):
1. 函数名作为一个值使用时,该函数自动地转换为指针;
2. 可以直接使用指向函数的指针来调用该函数,无须提前解引用指针;
3. 使用重载函数时,上下文必须清晰地界定到底应该选用哪个函数(即返回类型、形参列表精准匹配);
4. 在函数指针作为函数形参的情况下,函数类型实际上作为指针使用(编译器自动转换);在函数返回类型是指向函数的指针时,必须把返回类型写成指针形式,编译器不会自动地将函数返回类型当成对应的指针类型处理;
5. 明确函数类型和函数指针类型的区别,int(int*,int)是函数类型,int(*)(int*,int)是函数指针类型。
***简化使用函数指针代码的方法[1][3]
当函数指针作为函数的形参时,函数的声明会因为直接使用函数指针类型而显得冗长且繁琐。然而,使用类型别名和decltype能简化使用了函数指针的代码,简化示例如下:
bool lengthCompare(const string &,const string &); // 函数原型
// Func和Func2是函数类型(下述两行代码等效)
typedef bool Func(const string &,const string &);
typedef decltype(lengthCompare) Func2;
// FuncP和FuncP2是指向函数的指针(下述两行代码等效)
typedef bool (*FuncP)(const string &,const string &);
typedef decltype(lengthCompare) *FuncP2;
二、基于动态链接库(DLL)的函数调用方式
在C++高级编程语言中,可以使用LoadLibrary和GetProcAddress函数进行动态链接库内函数的动态加载使用。
// 1.导入头文件
#include <windows.h>
#include <iostream>// 2.使用LoadLibrary函数加载DLL文件
HINSTANCE hDll = LoadLibrary("DLL文件存储地址");
if (hDll == NULL)
{std::cout<< "DLL file cannot be opened!" <<endl;
}// 3.加载DLL成功后,使用GetProcAddress函数来获取DLL中函数的地址
// 假设DLL中有一个名为ExampleFunction的函数,其原型为int ExampleFunction(int arg1,int arg2)
typedef int(*PFN_EXAMPLE_FUNCTION)(int, int);
PFN_EXAMPLE_FUNCTION pfn = (PFN_EXAMPLE_FUNCTION)GetProcAddress(hDll,"ExampleFunction");
if (pFunction == NULL)
{std::cout<< "DLL file cant be open!" <<endl;FreeLibrary(hDll);
}// 通过函数指针来调用函数
int result = pfn(1, 2);
FreeLibrary(hDll);
参考资料:
[1] C++ Primer中文版:第5版 /(美)李普曼(Lippman,S.B.),(美)拉乔伊(Lajoie,J.),(美)默(Moo,B.E.)著;王刚,杨巨峰译. —北京:电子工业出版社,2013.9.
[2] C++数据类型以及函数设计学习记录_c++数据类型函数-CSDN博客
[3] C++处理类型方法-学习记录-CSDN博客