C++中参数传递方式
在 C++ 中,函数的参数传递可以分为值传递、引用传递和指针传递三种方式。下面简要介绍这三种传参方式的特点:
struct personInfo{
int age;
string name;
int sex;
}
值传递:
//结构体作为参数传入
void func(const personInfo & person) {
// 只可读,不可写
}
//传入结构体对象副本, 可读可写,但是不会对原始对象产生改变
void func(personInfo info){
info.age = 10;
info.name = "tom";
info.sex = 1;
std::cout << "changeInfo: " << info.age << " " << info.name << " " << info.sex << std::endl;
}
- 通过将实参的值复制给形参来传递参数。
- 优点是简单、安全,避免了对实参的修改影响到原始数据。
- 缺点是可能涉及到大量的数据复制,对性能有一定影响。
- 适合传递小数据类型或不需要修改实参的情况。
引用传递:
//直接传入对象地址,相当于操作的参数是对象本身
void func(personInfo& info){
//对于形参的操作,都会作用到原始数据上去
}
- 通过引用(&)将实参的地址传递给形参,在函数内部可以直接操作原始数据。
- 优点是不会进行数据复制,节省内存和提高效率。
- 缺点是需要注意引用的生命周期,避免出现悬空引用问题。
- 适合传递大型数据结构或需要修改实参的情况。
指针传递:
void changeInfo(personInfo* info){
info->age = 18;
info->name = "tom";
info->sex = 1;
cout << "changeInfo: " << info->age << " " << info->name << " " << info->sex << endl;
}
- 通过指针将实参的地址传递给形参,需要使用指针解引用操作来访问实际数据。
- 优点是与引用传递相似,可以直接操作原始数据。
- 缺点是需要手动管理指针的生命周期,存在空指针和野指针风险。
- 适合需要传递可空参数或需要动态分配内存的情况。
#include <iostream>
#include <time.h>
using namespace std;
typedef void (*FuncPrint) ();
typedef int (*FuncCal)(int,int);
string getCurrentDate(){
// 获取当前日期
time_t now = time(0);
tm *ltm = localtime(&now);
char buf[30];
strftime(buf, sizeof(buf), "%Y-%m-%d", ltm);
return string(buf);
}
void printCurrentDate(){
cout << "current data is :" << getCurrentDate() << endl;
}
void registerPrintFunc(FuncPrint func){
// 注册函数
func();
}
int add(int lval, int rval){
return lval + rval;
}
int sub(int lval, int rval){
return lval - rval;
}
int divCal(int lval, int rval){
if(rval == 0){
cout << "除数不能为0" << endl;
exit(0);
}
return lval / rval;
}
int mul(int lval, int rval){
return lval * rval;
}
void registerCalcFunc(FuncCal func, int lval, int rval){
// 注册函数
int result = func(lval,rval);
cout << "result is :" << result << endl;
}
void doExcute(){
registerPrintFunc(printCurrentDate);
registerCalcFunc(add, 10,20);
registerCalcFunc(sub, 10,20);
registerCalcFunc(divCal, 10,20);
registerCalcFunc(mul, 10,20);
return;
}
int main(){
doExcute();
return 0;
}
将函数指针作为对象传入的好处包括:
-
回调机制:实现灵活的回调功能,允许对象在适当的时候调用传入的函数指针。
-
事件处理:常用于事件处理机制,例如在特定事件发生时调用传入的函数指针。
-
异步操作通知:可用于异步操作完成后通知调用者,避免阻塞线程。
-
定时器:可用于定时器实现,例如定时执行传入的函数。
-
增加代码灵活性:使代码更具灵活性和可重用性,因为可以根据需要动态传入不同的函数。
-
清晰结构:使代码结构更清晰,易于维护和扩展,因为将函数指针与对象的关联明确化。