求c语言中static的用法,啥时候定义要加上他啊?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了求c语言中static的用法,啥时候定义要加上他啊?相关的知识,希望对你有一定的参考价值。

如题,总是掌握不好static的用法。详细点,举些例子。谢谢。

下面是C++中static的用法,C语中类似,只是没有不用管与类相关的.

C++的static有两种用法:面向过程程序设计中的static和面向对象程序设计中的static。前者应用于普通变量和函数,不涉及类;后者主要说明static在类中的作用。

一、面向过程设计中的static

1、静态全局变量

在全局变量前,加上关键字static,该变量就被定义成为一个静态全局变量。我们先举一个静态全局变量的例子,如下:

//Example 1#include <iostream.h>void fn();static int n; //定义静态全局变量void main() n=20; cout<<n<<endl; fn();void fn() n++; cout<<n<<endl;
静态全局变量有以下特点:
该变量在全局数据区分配内存;
未经初始化的静态全局变量会被程序自动初始化为0(自动变量的值是随机的,除非它被显式初始化);
静态全局变量在声明它的整个文件都是可见的,而在文件之外是不可见的;
静态变量都在全局数据区分配内存,包括后面将要提到的静态局部变量。对于一个完整的程序,在内存中的分布情况如下图:
代码区
全局数据区
堆区
栈区

一般程序的由new产生的动态数据存放在堆区,函数内部的自动变量存放在栈区。自动变量一般会随着函数的退出而释放空间,静态数据(即使是函数内部的静 态局部变量)也存放在全局数据区。全局数据区的数据并不会因为函数的退出而释放空间。细心的读者可能会发现,Example 1中的代码中将

static int n; //定义静态全局变量
改为
int n; //定义全局变量
程序照样正常运行。
的确,定义全局变量就可以实现变量在文件中的共享,但定义静态全局变量还有以下好处:
静态全局变量不能被其它文件所用;
其它文件中可以定义相同名字的变量,不会发生冲突;
您可以将上述示例代码改为如下:

//Example 2//File1#include <iostream.h>void fn();static int n; //定义静态全局变量void main() n=20; cout<<n<<endl; fn();//File2#include <iostream.h>extern int n;void fn() n++; cout<<n<<endl;
编译并运行Example 2,您就会发现上述代码可以分别通过编译,但运行时出现错误。 试着将
static int n; //定义静态全局变量
改为
int n; //定义全局变量
再次编译运行程序,细心体会全局变量和静态全局变量的区别。
2、静态局部变量

在局部变量前,加上关键字static,该变量就被定义成为一个静态局部变量。

我们先举一个静态局部变量的例子,如下:

//Example 3#include <iostream.h>void fn();void main() fn(); fn(); fn();void fn() static n=10; cout<<n<<endl; n++;
通常,在函数体内定义了一个变量,每当程序运行到该语句时都会给该局部变量分配栈内存。但随着程序退出函数体,系统就会收回栈内存,局部变量也相应失效。
但有时候我们需要在两次调用之间对变量的值进行保存。通常的想法是定义一个全局变量来实现。但这样一来,变量已经不再属于函数本身了,不再仅受函数的控制,给程序的维护带来不便。
静态局部变量正好可以解决这个问题。静态局部变量保存在全局数据区,而不是保存在栈中,每次的值保持到下一次调用,直到下次赋新值。
静态局部变量有以下特点:

该变量在全局数据区分配内存;
静态局部变量在程序执行到该对象的声明处时被首次初始化,即以后的函数调用不再进行初始化;
静态局部变量一般在声明处初始化,如果没有显式初始化,会被程序自动初始化为0;
它始终驻留在全局数据区,直到程序运行结束。但其作用域为局部作用域,当定义它的函数或语句块结束时,其作用域随之结束;
3、静态函数

在函数的返回类型前加上static关键字,函数即被定义为静态函数。静态函数与普通函数不同,它只能在声明它的文件当中可见,不能被其它文件使用。

静态函数的例子:

//Example 4#include <iostream.h>static void fn();//声明静态函数void main() fn();void fn()//定义静态函数 int n=10; cout<<n<<endl;
定义静态函数的好处:
静态函数不能被其它文件所用;
其它文件中可以定义相同名字的函数,不会发生冲突;
二、面向对象的static关键字(类中的static关键字)

1、静态数据成员

在类内数据成员的声明前加上关键字static,该数据成员就是类内的静态数据成员。先举一个静态数据成员的例子。

//Example 5#include <iostream.h>class Myclasspublic: Myclass(int a,int b,int c); void GetSum();private: int a,b,c; static int Sum;//声明静态数据成员;int Myclass::Sum=0;//定义并初始化静态数据成员Myclass::Myclass(int a,int b,int c) this->a=a; this->b=b; this->c=c; Sum+=a+b+c;void Myclass::GetSum() cout<<"Sum="<<Sum<<endl;void main() Myclass M(1,2,3); M.GetSum(); Myclass N(4,5,6); N.GetSum(); M.GetSum();
可以看出,静态数据成员有以下特点:
对于非静态数据成员,每个类对象都有自己的拷贝。而静态数据成员被当作是类的成员。无论这个类的对象被定义了多少个,静态数据成员在程序中也只有一份拷 贝,由该类型的所有对象共享访问。也就是说,静态数据成员是该类的所有对象所共有的。对该类的多个对象来说,静态数据成员只分配一次内存,供所有对象共 用。所以,静态数据成员的值对每个对象都是一样的,它的值可以更新;
静态数据成员存储在全局数据区。静态数据成员定义时要分配空间,所以不能在类声明中定义。在Example 5中,语句int Myclass::Sum=0;是定义静态数据成员;
静态数据成员和普通数据成员一样遵从public,protected,private访问规则;
因为静态数据成员在全局数据区分配内存,属于本类的所有对象共享,所以,它不属于特定的类对象,在没有产生类对象时其作用域就可见,即在没有产生类的实例时,我们就可以操作它;
静态数据成员初始化与一般数据成员初始化不同。静态数据成员初始化的格式为:
<数据类型><类名>::<静态数据成员名>=<值>
类的静态数据成员有两种访问形式:
<类对象名>.<静态数据成员名> 或 <类类型名>::<静态数据成员名>
如果静态数据成员的访问权限允许的话(即public的成员),可在程序中,按上述格式来引用静态数据成员 ;
静态数据成员主要用在各个对象都有相同的某项属性的时候。比如对于一个存款类,每个实例的利息都是相同的。所以,应该把利息设为存款类的静态数据成员。这 有两个好处,第一,不管定义多少个存款类对象,利息数据成员都共享分配在全局数据区的内存,所以节省存储空间。第二,一旦利息需要改变时,只要改变一次, 则所有存款类对象的利息全改变过来了;
同全局变量相比,使用静态数据成员有两个优势:
静态数据成员没有进入程序的全局名字空间,因此不存在与程序中其它全局名字冲突的可能性;
可以实现信息隐藏。静态数据成员可以是private成员,而全局变量不能;

2、静态成员函数
与静态数据成员一样,我们也可以创建一个静态成员函数,它为类的全部服务而不是为某一个类的具体对象服务。静态成员函数与静态数据成员一样,都是类的内部 实现,属于类定义的一部分。 普通的成员函数一般都隐含了一个this指针,this指针指向类的对象本身,因为普通成员函数总是具体的属于某个类的具体对象的。通常情况下,this 是缺省的。如函数fn()实际上是this->fn()。但是与普通函数相比,静态成员函数由于不是与任何的对象相联系,因此它不具有this指 针。从这个意义上讲,它无法访问属于类对象的非静态数据成员,也无法访问非静态成员函数,它只能调用其余的静态成员函数。 下面举个静态成员函数的例子。

//Example 6#include <iostream.h>class Myclasspublic: Myclass(int a,int b,int c); static void GetSum();/声明静态成员函数private: int a,b,c; static int Sum;//声明静态数据成员;int Myclass::Sum=0;//定义并初始化静态数据成员Myclass::Myclass(int a,int b,int c) this->a=a; this->b=b; this->c=c; Sum+=a+b+c; //非静态成员函数可以访问静态数据成员void Myclass::GetSum() //静态成员函数的实现// cout<<a<<endl; //错误代码,a是非静态数据成员 cout<<"Sum="<<Sum<<endl;void main() Myclass M(1,2,3); M.GetSum(); Myclass N(4,5,6); N.GetSum(); Myclass::GetSum();

关于静态成员函数,可以总结为以下几点:
出现在类体外的函数定义不能指定关键字static;
静态成员之间可以相互访问,包括静态成员函数访问静态数据成员和访问静态成员函数;
非静态成员函数可以任意地访问静态成员函数和静态数据成员;
静态成员函数不能访问非静态成员函数和非静态数据成员;
由于没有this指针的额外开销,因此静态成员函数与类的全局函数相比速度上会有少许的增长;
调用静态成员函数,可以用成员访问操作符(.)和(->)为一个类的对象或指向类对象的指针调用静态成员函数,也可以直接使用如下格式:
<类名>::<静态成员函数名>(<参数表>)
调用类的静态成员函数。

参考资料:http://zhidao.baidu.com/question/33573568.html?si=2

参考技术A #include"T1.h"
#include<iostream>
using namespace std;
int* Static();
static int Sta=100;
int Show();
int Le=1;
int main(int argc,char *argv[])

int Sh=0;
Sh=Show(); //10 返回的是静态变量L的值.
cout<<Sh<<endl;
Sh=Show(); //20 同上.同样的调用却不同的返回值,就是因为静态变量.
cout<<Sh<<endl;
int *p=0;
cout<<&Le<<endl;
p=Static();
cout<<"*p = "<<*p<<endl;
cout<<p<<endl;
/* cout<<Len<<endl; */
/*这句无法通过编译,因为Len这个变量的名字的作用域只是在Static()这个函数中,
过了这个函数就被立即销毁,其内部实现应该是一个栈元素弹出的操作,但它所代表的那块堆内存却因为是
static 全局静态变量,存储于应用程序的堆中而得到永生,这个变量占用的地盘只有在程
序结束,由系统自动收回,别无他法..*/
Show();
cin.get();

int* Static()

static int Len=0;
/*如果直接使用int Len=0,将无法通过编译,因为int Len=0;申请的是局部变量,
保存在栈中,函数返回后将被删除,而static int Len=0;申请的变量是
保存在全局内存区上*/
cout<<"Len = "<<Len<<endl;
cout<<&Len<<endl;
return &Len; /*这里返回的必须是永远存在的内存区域,否则报错*/

int Show()

static int L=0; //只会被定义一次;
L=L+10;
return L;
;
参考技术B 关键字static的作用是什么?
这个简单的问题很少有人能回答完全。在C语言中,关键字static有三个明显的作用:
•; 在函数体,一个被声明为静态的变量在这一函数被调用过程中维持其值不变。
•; 在模块内(但在函数体外),一个被声明为静态的变量可以被模块内所用函数访问,但不能被模块外其它函数访问。它是一个本地的全局变量。
•; 在模块内,一个被声明为静态的函数只可被这一模块内的其它函数调用。那就是,这个函数被限制在声明它的模块的本地范围内使用。

例子可以参考我的下面URL

参考资料:http://www.52rd.com/Blog/Detail_RD.Blog_imjacob_5297.html

本回答被提问者采纳

C++中,啥时候 必须 用类名加作用域符调用函数? 有static修饰的成员函数被 对象调用会发生啥?

FromHandle((HBRUSH)GetStockObject(NULL_BRUSH));的返回值是*m_brush用*m_brush 调用 FromHandle 返回值怎么存?*m_brush-> FromHandle( (HBRUSH)GetStockObject(NULL_BRUSH) );什么时候 必须 用类名加作用域符调用函数?问题有些多,求大神指教

一、二、什么叫栈,什么叫堆?操作系统内存分配的两个概念,都是指一段内存空间当程序动态运行的时候,比如说进入一个函数,而你在函数中定义了一些变量,在这个函数的开头就会从"栈"分配一些空间给这些变量,当这个函数退出以后,这些空间就释放了."堆"是为了弥补'栈'分配方式的不足而提出的另外一种分配方式.'栈'分配的不足是:1某一个函数占用空间的大小必须在编译的时候就知道,否则不能用栈式分配,2'栈'分配的空间在函数退出时就释放了,如果退出函数以后还要使用的话,就不能用栈式分配栈式分配的'已使用空间'和'未使用空间是连续的,而堆式则是不连续的(不一定)对应到C/C++中,inta这种变量定义,用的是栈式分配,而new或是malloc,则是堆式分配三、什么叫接口接口(interface)用来定义一种程序的协定。实现接口的类或者结构要与接口的定义严格一致。有了这个协定,就可以抛开编程语言的限制(理论上)。接口可以从多个基接口继承,而类或结构可以实现多个接口。接口可以包含方法、属性、事件和索引器。接口本身不提供它所定义的成员的实现。接口只指定实现该接口的类或接口必须提供的成员。接口好比一种模版,这种模版定义了对象必须实现的方法,其目的就是让这些方法可以作为接口实例被引用。接口不能被实例化。类可以实现多个接口并且通过这些实现的接口被索引。接口变量只能索引实现该接口的类的实例。例子:interfaceIMyExamplestringthis[intindex]get;set;eventEventHandlerEven;voidFind(intvalue);stringPointget;set;publicdelegatevoidEventHandler(objectsender,Evente);上面例子中的接口包含一个索引this、一个事件Even、一个方法Find和一个属性Point。接口可以支持多重继承。就像在下例中,接口"IComboBox"同时从"ITextBox"和"IListBox"继承。interfaceIControlvoidPaint();interfaceITextBox:IControlvoidSetText(stringtext);interfaceIListBox:IControlvoidSetItems(string[]items);interfaceIComboBox:ITextBox,IListBox类和结构可以多重实例化接口。就像在下例中,类"EditBox"继承了类"Control",同时从"IDataBound"和"IControl"继承。interfaceIDataBoundvoidBind(Binderb);publicclassEditBox:Control,IControl,IDataBoundpublicvoidPaint();publicvoidBind(Binderb)在上面的代码中,"Paint"方法从"IControl"接口而来;"Bind"方法从"IDataBound"接口而来,都以"public"的身份在"EditBox"类中实现。说明:1、C#中的接口是独立于类来定义的。这与C++模型是对立的,在C++中接口实际上就是抽象基类。2、接口和类都可以继承多个接口。3、而类可以继承一个基类,接口根本不能继承类。这种模型避免了C++的多继承问题,C++中不同基类中的实现可能出现冲突。因此也不再需要诸如虚拟继承和显式作用域这类复杂机制。C#的简化接口模型有助于加快应用程序的开发。4、一个接口定义一个只有抽象成员的引用类型。C#中一个接口实际所做的,仅仅只存在着方法标志,但根本就没有执行代码。这就暗示了不能实例化一个接口,只能实例化一个派生自该接口的对象。5、接口可以定义方法、属性和索引。所以,对比一个类,接口的特殊性是:当定义一个类时,可以派生自多重接口,而你只能可以从仅有的一个类派生。四、什么叫宏在用一种不熟悉的宏语言进行宏编程时,可以这样做,首先记录下用户想要宏完成什么,然后打开宏文件并尝试理解命令结构如何工作。也可以修改命令以调整宏。一些宏语言,比如GreatPlains账务(?accounting)软件的Dexterity运行时引擎,不能从其它数据源(如由逗号分隔的文本文件)导入数据。这一限制可以通过用更强大的编程语言,如VBA来创建一个计算机程序在此弱编程语言里生成一个特别的宏来解决。例如,可以对MicrosoftExcel宏编程从扩展样式表或文本文件中读取数据并创建GreatPlains.mac文件,这一文件被用于将特定的数据导入GreatPlains.需要针对每一个新的数据集合声称新的.mac文件。五、什么叫构造函数成员初始化表构造函数初始化列表以一个冒号开始,接着是以逗号分隔的数据成员列表,每个数据成员后面跟一个放在括号中的初始化式。例如:[code]classCExamplepublic:inta;floatb;//构造函数初始化列表CExample():a(0),b(8.8)//构造函数内部赋值CExample()a=0;b=8.8;;[/code]上面的例子中两个构造函数的结果是一样的。上面的构造函数(使用初始化列表的构造函数)显式的初始化类的成员;而没使用初始化列表的构造函数是对类的成员赋值,并没有进行显式的初始化。初始化和赋值对内置类型的成员没有什么大的区别,像上面的任一个构造函数都可以。对非内置类型成员变量,为了避免两次构造,推荐使用类构造函数初始化列表。但有的时候必须用带有初始化列表的构造函数:1.成员类型是没有默认构造函数的类。若没有提供显示初始化式,则编译器隐式使用成员类型的默认构造函数,若类没有默认构造函数,则编译器尝试使用默认构造函数将会失败。2.const成员或引用类型的成员。因为const对象或引用类型只能初始化,不能对他们赋值。3.在继承里面,只有初始化列表可以构造父类的private成员。初始化数据成员与对数据成员赋值的含义是什么?有什么区别?首先把数据成员按类型分类并分情况说明:1.内置数据类型,复合类型(指针,引用)在成员初始化列表和构造函数体内进行,在性能和结果上都是一样的2.用户定义类型(类类型)结果上相同,但是性能上存在很大的差别。因为类类型的数据成员对象在进入函数体前已经构造完成,也就是说在成员初始化列表处进行构造对象的工作,调用构造函数,在进入函数体之后,进行的是对已经构造好的类对象的赋值,又调用个拷贝赋值操作符才能完成(如果并未提供,则使用编译器提供的默认按成员赋值行为)Note:初始化列表的成员初始化顺序:C++初始化类成员时,是按照声明的顺序初始化的,而不是按照出现在初始化列表中的顺序。[code]Example:classCMyClassCMyClass(intx,inty);intm_x;intm_y;;CMyClass::CMyClass(intx,inty):m_y(y),m_x(m_y)[/code]你可能以为上面的代码将会首先做m_y=I,然后做m_x=m_y,最后它们有相同的值。但是编译器先初始化m_x,然后是m_y,,因为它们是按这样的顺序声明的。结果是m_x将有一个不可预测的值。有两种方法避免它,一个是总是按照你希望它们被初始化的顺序声明成员,第二个是,如果你决定使用初始化列表,总是按照它们声明的顺序罗列这些成员。这将有助于消除混淆。六、什么叫函数参数表所谓的函数参数表就是函数所用到的所有参数集合的表,比如说VB中API函数中各个函数的参数表/vbapi/index.asp七、什么叫参数列表你想要的应该就是oracle_home\admin\sid\pfile下的init.ora吧!八、什么叫const关于C++中的const关键字的用法非常灵活,而使用const将大大改善程序的健壮性,现将本人的一些体会总结如下,期望对大家有所帮助:一const基础如果const关键字不涉及到指针,我们很好理解,下面是涉及到指针的情况:intb=500;constint*a=&b;[1]intconst*a=&b;[2]int*consta=&b;[3]constint*consta=&b;[4]如果你能区分出上述四种情况,那么,恭喜你,你已经迈出了可喜的一步。不知道,也没关系,我们可以参考《Effectivec++》Item21上的做法,如果const位于星号的左侧,则const就是用来修饰指针所指向的变量,即指针指向为常量;如果const位于星号的右侧,const就是修饰指针本身,即指针本身是常量。因此,[1]和[2]的情况相同,都是指针所指向的内容为常量(const放在变量声明符的位置无关),这种情况下不允许对内容进行更改操作,如不能*a=3;[3]为指针本身是常量,而指针所指向的内容不是常量,这种情况下不能对指针本身进行更改操作,如a++是错误的;[4]为指针本身和指向的内容均为常量。另外const的一些强大的功能在于它在函数声明中的应用。在一个函数声明中,const可以修饰函数的返回值,或某个参数;对于成员函数,还可以修饰是整个函数。有如下几种情况,以下会逐渐的说明用法:A&operator=(constA&a);voidfun0(constA*a);voidfun1()const;//fun1()为类成员函数constAfun2();二const的初始化先看一下const变量初始化的情况1)非指针const常量初始化的情况:Ab;constAa=b;2)指针(引用)const常量初始化的情况:A*d=newA();constA*c=d;或者:constA*c=newA();引用:Af;constA&e=f;//这样作e只能访问声明为const的函数,而不能访问一般的成员函数;[思考1]:以下的这种赋值方法正确吗?constA*c=newA();A*e=c;[思考2]:以下的这种赋值方法正确吗?A*constc=newA();A*b=c;三作为参数和返回值的const修饰符其实,不论是参数还是返回值,道理都是一样的,参数传入时候和函数返回的时候,初始化const变量1修饰参数的const,如voidfun0(constA*a);voidfun1(constA&a);调用函数的时候,用相应的变量初始化const常量,则在函数体中,按照const所修饰的部分进行常量化,如形参为constA*a,则不能对传递进来的指针的内容进行改变,保护了原指针所指向的内容;如形参为constA&a,则不能对传递进来的引用对象进行改变,保护了原对象的属性。[注意]:参数const通常用于参数为指针或引用的情况;2修饰返回值的const,如constAfun2();constA*fun3();这样声明了返回值后,const按照"修饰原则"进行修饰,起到相应的保护作用。constRationaloperator*(constRational&lhs,constRational&rhs)returnRational(lhs.numerator()*rhs.numerator(),lhs.denominator()*rhs.denominator());返回值用const修饰可以防止允许这样的操作发生:Rationala,b;Radionalc;(a*b)=c;一般用const修饰返回值为对象本身(非引用和指针)的情况多用于二目操作符重载函数并产生新对象的时候。[总结]一般情况下,函数的返回值为某个对象时,如果将其声明为const时,多用于操作符的重载。通常,不建议用const修饰函数的返回值类型为某个对象或对某个对象引用的情况。原因如下:如果返回值为某个对象为const(constAtest=A实例)或某个对象的引用为const(constA&test=A实例),则返回值具有const属性,则返回实例只能访问类A中的公有(保护)数据成员和const成员函数,并且不允许对其进行赋值操作,这在一般情况下很少用到。[思考3]:这样定义赋值操作符重载函数可以吗?constA&operator=(constA&a);四类成员函数中const的使用一般放在函数体后,形如:voidfun()const;如果一个成员函数的不会修改数据成员,那么最好将其声明为const,因为const成员函数中不允许对数据成员进行修改,如果修改,编译器将报错,这大大提高了程序的健壮性。五使用const的一些建议1要大胆的使用const,这将给你带来无尽的益处,但前提是你必须搞清楚原委;2要避免最一般的赋值操作错误,如将const变量赋值,具体可见思考题;3在参数中使用const应该使用引用或指针,而不是一般的对象实例,原因同上;4const在成员函数中的三种用法(参数、返回值、函数)要很好的使用;5不要轻易的将函数的返回值类型定为const;6除了重载操作符外一般不要将返回值类型定为对某个对象的const引用;本人水平有限,欢迎批评指正,可以联系kang_jd@163.com[思考题答案]1这种方法不正确,因为声明指针的目的是为了对其指向的内容进行改变,而声明的指针e指向的是一个常量,所以不正确;2这种方法正确,因为声明指针所指向的内容可变;3这种做法不正确;在constA::operator=(constA&a)中,参数列表中的const的用法正确,而当这样连续赋值的时侯,问题就出现了:Aa,b,c:(a=b)=c;因为a.operator=(b)的返回值是对a的const引用,不能再将c赋值给const常量。九、区分重载函数的标志就是参数列表不一样吗是的。所谓函数重载是指同一个函数名可以对应着多个函数的实现。例如,可以给函数名add()定义多个函数实现,该函数的功能是求和,即求两个操作数的和。其中,一个函数实现是求两个int型数之和,另一个实现是求两个浮点型数之和,再一个实现是求两个复数的和。每种实现对应着一个函数体,这些函数的名字相同,但是函数的参数的类型不同。这就是函数重载的概念。函数重载在类和对象的应用尤其重要。十、字符数组与字符串数组有什么区别具体的例子解释可以到这里看看十一、exit函数在main函数中我们通常使用return(0);这样的方式返回一个值。但这是限定在非void情况下的也就是voidmain()这样的形式。exit()通常是用在子程序中用来终结程序用的,使用后程序自动结束跳会操作系统。但在如果把exit用在main内的时候无论main是否定义成void返回的值都是有效的,并且exit不需要考虑#include#includeusingnamespacestd;intmain()exit(1);//等价于return(1); 参考技术A 必须使用类名调用函数的方式,一般常见于调用类中静态函数,因为静态函数不属于类的某个具体实例化对象,对象调用静态函数等同于使用类名方式,应该说能够使用对象调用静态函数方式仅仅是语法上支持,因为最直接的解释是静态函数里面没有this指针,所以可以说和具体对象无关(至于参数是那个类型的对象,那只是普通意义上的函数方式了)。
还有的时候使用类名限定是为了指明使用的是那个函数,因为有时可能因为同名遮蔽或者名称相同(实现不同)的二义性等原因,需要你指明你实际调用的是哪个函数。例子如下:
class B
public:
void fun()
;
class A:public B
public:
void fun()
this->B::fun();//体现了同名遮蔽和指定具体函数2重效果。

;追问

不对吧,this->fun()应该就是直接调用的基类B的函数,没有声明是虚函数啊
另外,有this->B::fun() 这种访问方法吗?

本回答被提问者和网友采纳

以上是关于求c语言中static的用法,啥时候定义要加上他啊?的主要内容,如果未能解决你的问题,请参考以下文章

求C语言memset的具体用法,啥时候必须用,啥时候可以不用以及可以用啥替换memset

请问在C语言中,auto和static分别代表啥意思,有啥作用,谢谢

static变量有啥作用

C/C++:static用法总结

c语言中,malloc和free是啥意思?

c语言 求平均数有啥函数?