第二篇 C++函数指针用法

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;
}

将函数指针作为对象传入的好处包括:

  • 回调机制:实现灵活的回调功能,允许对象在适当的时候调用传入的函数指针。

  • 事件处理:常用于事件处理机制,例如在特定事件发生时调用传入的函数指针。

  • 异步操作通知:可用于异步操作完成后通知调用者,避免阻塞线程。

  • 定时器:可用于定时器实现,例如定时执行传入的函数。

  • 增加代码灵活性:使代码更具灵活性和可重用性,因为可以根据需要动态传入不同的函数。

  • 清晰结构:使代码结构更清晰,易于维护和扩展,因为将函数指针与对象的关联明确化。

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C++智能指针:shared_ptr⽤法详解 C++智能指针:shared_ptr⽤法详解 shared_ptr是C++11⾥的新特性,其包装了new操作符在堆上分配的动态对象。如: shared_ptr<int> sp1(new int(100)); //相当于 //int *sp1=new int(100); //auto sp1=make_shared<int>(100); 它与普通指针相⽐,最⼤的不同点就是shared_ptr是⼀个类,当对象⽣命周期结束时,会⾃动调⽤其析构函数,释放内存。⽽不再需要程 序员显⽰地调⽤delete关键字。 同时,shared_ptr重载了"*"和"->"操作符以模仿原始指针的⾏为,并且提供了显⽰bool类型转换以判断指针的有效性。 shared_ptr<int> sp1(new int(100)); assert(sp1); *sp1=200; shared_ptr<string> sp2(new string("Hello")); assert(sp2->size()==5); 我们还可以使⽤shared_ptr的成员函数get()获取原始指针 shared_ptr<int> sp1(new int(100)); int *Int_ptr=sp1.get(); shared_ptr⾥的reset()函数 shared_ptr⾥有个成员函数use_count(),⽤于返回该对象的引⽤计数。 shared_ptr<int> sp1(new int(100)); cout<<"当前计数: "<<sp1.use_count()<<endl; auto sp2=sp1; cout<<"当前计数: "<<sp1.use_count()<<endl; { auto sp3=sp2; cout<<"当前计数: "<<sp1.use_count()<<endl; } cout<<"当前计数: "<<sp1.use_count()<<endl; 当⼀个shared_ptr对象调⽤reset()函数时,它的作⽤时将引⽤计数减⼀,调⽤本⾝的对象的引⽤计数变为0. shared_ptr<int> sp1(new int(100)); cout<<"当前计数: "<<sp1.use_count()<<endl; auto sp2=sp1; cout<<"当前计数: "<<sp1.use_count()<<endl; { auto sp3=sp2; cout<<"当前计数: "<<sp1.use_count()<<endl; } cout<<"当前计数: "<<sp1.use_count()<<endl; sp2.reset();//这⾥换成sp1.reset(),可以发现sp2的计数为1,sp1的计数为0. cout << "sp2当前计数: " << sp2.use_count() << endl; cout << "sp1当前计数: " << sp2.use_count() << endl; 上⾯代码运⾏后,sp2的计数为0,sp1的计数为1。若将sp2.reset()换位sp1.reset(),则sp2的计数为1,sp1的计数为0。 在每次对shared_ptr进⾏拷贝或者赋值的时候,都会使计数加1。 ⼯⼚函数 每次使⽤shared_ptr都需要显⽰的使⽤new关键字创建⼀个对象。固std库提供了⼀个⼯⼚函数make_shared()。 ⽤法: auto sp1=make_shared<int>(100); //相当于 shared_ptr<int> sp1(new int(100)); make_shared是⼀个泛型,<>⾥⾯为数据类型,()对应着new()⾥的东西,其返回值是⼀个shared_ptr类型的变量。 定制删除器 shared_ptr的构造函数可有多个参数,其中有⼀个是shared_ptr(Y *p,D d),第⼀个参数是要被管理的指针,它的含义与其构造函数的参 数相同。⽽第⼆个参数则告诉shared_ptr在析构时不要使⽤delete来操作指针p,⽽要⽤d来操作,即把delete p 换成d(p)。因此,我们 就可以⾃⼰制作⼀个删除器 如:对于传统的struct FILE的C⽂件操作,需要 FILE *fp=fopen("./1.txt","r"); //... //... fclose(fp); 若⽤shared_ptr,则可以这样做: shared_ptr<FILE> fp(fopen("./1.txt","r"), fclose); 离开作⽤域时,shared_ptr会⾃动调⽤fclose()函数关闭⽂件。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值