C++中,啥时候 必须 用类名加作用域符调用函数? 有static修饰的成员函数被 对象调用会发生啥?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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语言的双冒号是啥意思::
双冒号(::)用法:
1、表示“域操作符”。
2、直接用在全局函数前,表示是全局函数。
3、表示引用成员函数及变量,作用域成员运算符。
4、命名空间作用域符,即2直接用在全局函数前,表示是全局函数,在运算符等级中属于最高级的。
扩展资料:
1、在类外部声明成员函数。void Point::Area();
2、调用全局函数;
3、表示引用成员函数变量及作用域,作用域成员运算符 例:System::Math::Sqrt() 相当于System.Math.Sqrt()
4、调用类的静态方法: 如:CDisplay::display(...)
可以非正式地把域看作是一个可视窗口全局域的对象在它被定义的整个文件里,一直到文件末尾都是可见的。
在一个函数内被定义的对象是局域的(local scope), 它只在定义其的函数体内可见。每个类维持一个域,在这个域之外 ,它的成员是不可见的。类域操作符告诉编译器后面的标识符可在该类的范围内被找到。
参考资料:
百度百科-域操作符
双冒号(::)用法:直接用在全局函数前,表示是全局函数,::一般还有一种用法,就是直接用在全局函数前,表示是全局函数。
::是C++里的“作用域分解运算符”。比如声明了一个类A,类A里声明了一个成员函数voidf(),但没有在类的声明里给出f的定义,在类外定义f时,就要写成voidA::f(),表示这个f()函数是类A的成员函数。
调用类的静态方法:
如:CDisplay::display(...)可以非正式地把域看作是一个可视窗口全局域的对象在它被定义的整个文件里,一直到文件末尾都是可见的。在一个函数内被定义的对象是局域的(local scope), 它只在定义其的函数体内可见。
以上内容参考:百度百科-域操作符
参考技术B 双冒号::,是C++语言里面的符号。并不是C语言的。它表示某个“类”里面的函数。 参考技术C 正如楼上,是作用域符号(::),表示后面的变量或函数是属于前面的类的。例如:
myclass::MyFunc()表示MyFunc()函数是类myclass的成员函数。 参考技术D c++中的名字空间限定
c语言里没有本回答被提问者采纳
以上是关于C++中,啥时候 必须 用类名加作用域符调用函数? 有static修饰的成员函数被 对象调用会发生啥?的主要内容,如果未能解决你的问题,请参考以下文章