首页技术成员函数调用成员函数?成员函数和非成员函数的区别

成员函数调用成员函数?成员函数和非成员函数的区别

编程之家2026-05-281196次浏览

今天给各位分享成员函数调用成员函数的知识,其中也会对成员函数和非成员函数的区别进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!

成员函数调用成员函数?成员函数和非成员函数的区别

C++的成员函数和普通函数

首先要知道类存在的理由,为何要面向对象。

C中的结构体就是定义一种数据格式,可以存储若干数据元素,并且它们的内存是连续的。

结构体的作用是封装一组有关联的属性,它们共同维护某种概念实体的状态。

在早期经典纯C工程当中,有经验的开发者早就开始利用结构体与函数指针实现简单的面向对象。

但是用结构体+函数指针使用不方便不灵活,所以C++最大的使命,面向对象就诞生了。

要注意的是C++与C的区别除了类之外,还有函数多态的特性、命名空间、STL等等特性。

成员函数调用成员函数?成员函数和非成员函数的区别

类相比于结构体+函数指针最大的优势就是两个字:继承

撤了一大堆废话,针对LZ的问题可以归结为,在没有属性的时候,只有函数,使用类好不好,或者说何时可以如此使用。

如果LZ学习过设计模式,那么这个问题就颇为清晰,类的存在是为了更灵活地描述某种概念实体以及对它的操作。

一个只有函数而没有属性的类,其描述的实体可以认为是一种抽象的动作实体。

用通俗的话来讲,一个继承Animal的Cat类描述一个猫,猫有属性(形态,叫声,年龄等),也有动作(吃喝拉撒睡),这就是最经典LZ也熟知的一种类。

而抽象的动作类,就有比如一个继承File的DiskFile或者FtpFile等,它主要描述的是一组动作(读与写),它也许有状态(属性),也许没有。

成员函数调用成员函数?成员函数和非成员函数的区别

这种抽象的动作类为何而存在?经典的策略设计模式就会大量地使用这种写法。

比如你要做视频处理软件,视频需要解码与加码如果只是用纯函数的化你的代码就会如下丑陋:

if(0==strcmp(fileType,AVI)){

decode_AVI(file);

}elseif(0==strcmp(fileType,MP4)){

decode_MP4(file);

}

.....

if(0==strcmp(fileType,AVI)){

encode_AVI(file);

}elseif(0==strcmp(fileType,MP4)){

encode_MP4(file);

}但是如果你有一个类AVType,只有两个函数:encode、decode,然后有AVIType、MP4Type继承它,那么你的代码大致就是:

AVType*type=newAVIType();//orMP4Type

type->decode(file);

....

type->encode(file);当你的同类方法多起来(如rmvb、wmv、flv解码器等等),你就会发现后者有多优秀。

最后总结对LZ的问题的回答就是:

如果没有继承也不会存在潜在继承的可能,也就是说用不到C++的多态特新,那么没有属性的类就没有存在的必要。

今天闲的无聊,说了一堆废话,LZ跳着看就行了O(∩_∩)O~

派生类指针指向基类对象,如何调用其成员函数

用:pb->f();即可。

类A中有了虚函数就会再类的数据成员的最前面添加一个vfptr指针(void** vfptr),这个指针用来指向一个vtable表(一个函数指针数组)(一个类只有一个该表),该表存储着当前类的所有虚函数的地址。这样vfptr就成为了一个类似成员变量的存在。访问虚函数的时候通过vfptr间址找到vtable表,再间址进而找到要调用的函数。这样就在一定程度上摆脱了类型制约。

只要vptr的值不同,那么访问函数成员的时候使用的vtable表就不同,就可能访问到不同类的函数成员。B类对象中的vptr指向B类自己的vtable。

当B类继承A类的时候,因为A中有虚函数,编译器就自动的给B类添加vfprt指针和vtable表。也可以理解为B类继承来了A类中的那个vptr指针成员。

当A类指针指向B类对象时,发生假切割。要知道这个过程只是切掉A类中没有的那些成员,由于vptr是从A类中继承来的,所以这个量仍将保留。而对于vptr的值则不会改变,仍然指向B类的vtable表。所以访问F1函数的时候是通过B类的vtable表去寻址的,自然就是使用子类的函数。

当B类的指针指向A类的对象时(当B类存在新增数据成员时可能出错),同理。

而对于普通函数则受类型的制约,(因为没有vptr指针)使用哪个类的指针调用函数,那么所调用的就是那个累的函数。

普通函数通过对象或指针的类型来找所调用的函数,而虚函数是通过一个指针来找到所要调用的函数的。

如何定义和实现一个类的成员函数为回调函数

回调函数就是被调用者回头调用调用者的函数。回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用为调用它所指向的函数时,我们就说这是回调函数。回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。使用回调函数实际上就是在调用某个函数(通常是API函数)时,将自己的一个函数(这个函数为回调函数)的地址作为参数传递给那个被调用函数。而该被调用函数在需要的时候,利用传递的地址调用回调函数。回调函数,就是由你自己写的,你需要调用另外一个函数,而这个函数的其中一个参数,就是你的这个回调函数名。这样,系统在必要的时候,就会调用你写的回调函数,这样你就可以在回调函数里完成你要做的事。要定义和实现一个类的成员函数为回调函数需要做三件事:a.声明;b.定义; c.设置触发条件,就是在你的函数中把你的回调函数名作为一个参数,以便系统调用如:声明回调函数类型 typedef void(*FunPtr)(void);定义回调函数class A{public: static void callBackFun(void)//回调函数,必须声明为static{}};设置触发条件 void Funtype(FunPtr p){p();} void main(void){ Funtype(A::callBackFun);} C.回调函数与API函数回调和API非常接近,他们的共性都是跨层调用的函数。但区别是API是低层提供给高层的调用,一般这个函数对高层都是已知的;而回调正好相反,他是高层提供给底层的调用,对于低层他是未知的,必须由高层进行安装,这个安装函数其实就是一个低层提供的API,安装后低层不知道这个回调的名字,但它通过一个函数指针来保存这个回调函数,在需要调用时,只需引用这个函数指针和相关的参数指针。其实:回调就是该函数写在高层,低层通过一个函数指针保存这个函数,在某个事件的触发下,低层通过该函数指针调用高层那个函数。

文章到此结束,如果本次分享的成员函数调用成员函数和成员函数和非成员函数的区别的问题解决了您的问题,那么我们由衷的感到高兴!

bootstrap抽样方法原理(bootstrap官方网站)法师神器任务 猎人神器任务哪里接