logo资料库

面向对象(C++)笔记.pdf

第1页 / 共11页
第2页 / 共11页
第3页 / 共11页
第4页 / 共11页
第5页 / 共11页
第6页 / 共11页
第7页 / 共11页
第8页 / 共11页
资料共11页,剩余部分请下载后查看
1【C++】1.请答出const与#define相比,有何优点?答:const常量有数据类型,而宏常量没有数据类型。编译器可以对前者进行类型安全检查,而对后者只进行字符替换,没有类型安全检查,并且在字符替换可能会产生意料不到的错误。(有些集成化的调试工具可以对const常量进行调试,但是不能对宏常量进行调试。)【C++】2.C++语言内存的分配方式有几种?答:(1)从静态存储区域分配。内存在程序编译的时候已经分配,这部分内存在程序的整个运行期间都存在。例如全局变量、静态变量。(2)在栈上创建。在执行函数时,函数内局部变量的存储单元可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率高,但分配的内存容量有限。(3)从堆上分配,亦称动态内存分配。程序在运行的时候用new或malloc申请任意多少的内存,程序员自己负责在何时用delete或free释放内存。动态内存的生存期由程序员决定,使用非常灵活,但问题也最多。【static】3.static全局变量与普通全局变量有什么区别?static局部变量和普通局部变量有什么区别?答:全局变量(外部变量)的说明之前再冠以static就构成静态的全局变量。全局变量本身就是静态存储方式,静态全局变量当然也是静态存储方式。这两者在存储方式上并无不同。这两者的区别存在于非静态全局变量的作用域是整个源程序,当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的。而静态全局变量则限制了其作用域,即只在定义该变量的源文件内有效,在同一源程序的其他源文件中不能使用。由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用,因此可以避免在其他源文件中引起错误。因此,把局部变量改变为静态变量后是改变了它的存储方式即改变了它的生存期。把全局变量改变为静态变量后是改变了它的作用域,限制了它的使用范围。static全局变量与普通的全局变量的区别:static全局变量只初始化一次,防止在其他文件单元中被引用。static局部变量与普通局部变量的区别:static局部变量只被初始化一次,下一次依据上一次结果值。【变量】4.变量的存储类包括四类:(1)自动变量:只有在函数内或复合语句内定义的局部变量,才能被定义为自动变量。程序中大多数变量属于自动变量,其主要特点是临时性。未给定初值时,它的初值是不确定的。(2)静态变量:在程序编译时预分配,并在程序执行之前就被确定存储单元。定义静态的局部变量时,未指定初值,则系统自动给静态的局部变量赋一个二进位信息全为0的初值。(3)外部变量:一个在函数之外某处定义的全局变量,它或在源程序文件的后面定义,或在别的源程序文件中定义。(4)寄存器变量:一般情况下,变量的值是存放在内存中的。当程序中用到哪一个变量的值时,需要将内存中该变量的值送到CPU中的运算器。经过运算器运算之后,如果需要存数,再从运算器中将数据送到内存存放。如果程序中有一些变量使用频繁,则存取变量的值要花不少时间。为了提高执行效率,C++允许将局部变量的值放在CPU中的寄存器中,需要用时直接丛寄存器取出,不必再到内存中去存取。这种放在CPU的寄存器中的变量叫做寄存器变量。只有int型、char型及指针类型的局部变量和形参才可以是寄存器变量。全局
2变量或其他复杂数据类型的变量都不可以是寄存器变量。(由于离开函数或分程序后,值就消失)将一个局部变量指定为寄存器变量时,是提醒编译程序,这个变量在程序中使用得十分频繁,在为该变量分配存储空间时,有可能的话,尽量为它分配寄存器,因为访问寄存器要比访问存储单元来得快。将一个形参的存储类指定为寄存器时,可能是因为要访问某些特殊设备的驱动程序,这些设备的驱动程序要求以寄存器为参数与系统进行信息传递。【内联函数】5.内联函数:在编译时将函数体的代码直接插入到函数调用处,将调用函数的方式改为顺序执行直接插入的程序代码,这样就减少了程序执行时间,这个过程称为函数的内联。这种嵌入到主调函数中的函数称为内联函数。在程序执行过程中,当调用一个函数时,需要保存现场数据和返回地址(以便在函数调用之后继续执行),然后转到被调用函数代码的起始地址去执行。被调用函数执行完以后,又要取出先前保存的现场数据和返回地址,转回到主调函数继续执行。这些操作都要花费一定的时间,使用内联函数可以节省参数传递、控制转移等开销,但目标文件的存储空间却增大了。内联函数实质上是以空间来换取时间的,因此一般只将规模很小(一般为5个语句以下)而使用频繁的函数声明为内联函数。【宏】6.设宏定义#defineP(x)x/x,则执行语句cout<
3到’\0’的地方之间的内容全部输出。补充:在C语言中printf(“%s”,串首地址)用来输出字符串,printf(“%c”,字符)用来输出字符,如果用printf(“%c”,字符地址)则会将字符地址对应的ASCII码变成字符输出。【指针,数组】*11.若有如下定义:char*aa[2]={"abcd","ABCD"};则可以这样理解:*aa存放的是指针数组的首地址,aa中存放的是地址的地址,故输出aa会显示一段地址。具体如下:cout<
4【析构函数】17.析构函数和构造函数一样,也是类的一个公有成员函数,没有返回值类型说明,也不能被指定为void类型。和构造函数不同的是,析构函数不接收任何参数,但可以是虚函数。由于析构函数没有函数参数,因此它不能被重载。一个类只有一个析构函数。【构造函数】18.假定MyClass为一个类,则执行MyClassa,b(2),*p;语句时,自动调用该类的构造函数的次数为(A)。A.2B.3C.4D.5评:定义一个指向类对象的指针变量时,并不创建一个对象,因此,定义指向类对象的指针变量时,并不会调用构造函数(包括默认构造函数)进行初始化。本题如果改为MyClassa,b(2),*p=newMyClass;则结果为调用构造函数3次。【静态数据成员】19.静态数据成员的初始化与该类的构造函数无关,不能在构造函数中对它进行初始化。静态数据成员初始化:intClass::static_data_member=0;(已有如下定义:staticintstatic_data_member;),另外,初始化只能在类体外进行。补充:在类体中不允许对数据成员进行初始化。【常数据成员】20.只能通过成员初始化列表的方式来生成构造函数对该数据成员初始化。如下:Class(inti):x(i){}(Class为类名,已有如下定义:constintx;)。【常成员函数】21.只有常成员函数才有资格操作常对象。常对象只能调用常成员函数。【构造函数】22.当程序执行到对象定义时,调用自动局部对象的构造函数。该对象的析构函数在对象离开范围时调用(即离开定义对象的块时,这一点很重要,假如一个对象obj在外部函数中被定义,而该函数又在main函数中被调用,那么当函数被调用时,创建obj对象,当函数调用结束,返回main函数时,则该对象已离开其作用域,此时即被删除)。自动对象的构造函数与析构函数在每次对象进入和离开范围时调用。假设生成派生类对象,基类和派生类都包含其他类的对象,则在建立派生类的对象时,首先执行基类成员对象的构造函数,接着执行基类的构造函数,然后执行派生类的成员对象的构造函数,最后才执行派生类的构造函数。析构函数的调用次序与调用构造函数的次序相反。【构造函数,拷贝构造函数】*23.分析程序写结果:#includeusingnamespacestd;classB{public:B(){cout<<"defaultconstructoriscalled"<
5BPlay(Bb){cout<<"functionPlay()nowisrunning"<
6别具有公有成员或私有成员的特性。(基类自身的成员可以访问基类中任何一个成员,但是通过基类的对象就只能访问其公有成员。)对于单个类来说,私有成员和保护成员没有什么区别。但对于继承来说,保护成员与私有成员则不同,保护成员可以被派生类的成员(注意,不是对象)访问,而私有成员不可以被派生类的成员访问。保护成员和公有成员又有所不同,保护成员即使在公有继承的情况下也不能被派生类的对象访问,而公有成员可以在公有继承的情况下,被派生类的对象访问。【多继承,二义性】26.基类和派生类中同时出现的同名函数,不存在二义性。因为如果不使用限定法,则派生类默认访问派生类函数。【虚基类】27.虚基类是这样一个类:它虽然被一个派生类间接地多次继承,但派生类却只继承一份该基类的成员,这样就避免了在派生类中访问这些成员时产生二义性。【虚基类,构造函数】*28.一般派生类不需要为间接基类提供构造函数的初始化值,它们只与直接基类打交道。对于非虚基类,在派生类的构造函数中初始化间接基类是不允许的,而对于虚基类,则必须在派生类中对虚基类初始化。如果在派生类的构造函数的成员初始化列表中没有列出对虚基类构造函数的调用,则表示使用该虚基类的默认构造函数。我们将建立对象时所指定的类称为最派生类。建立一个对象时,如果这个对象中含有从虚基类继承来的成员,则虚基类的成员是由最派生类的构造函数通过调用虚基类的构造函数进行初始化的,而且,只有最派生类的构造函数会调用虚基类的构造函数,该派生类的其他基类对虚基类构造函数的调用都被自动忽略,从而保证了虚基类的构造函数只被调用一次,从虚基类中继承来的数据成员只被初始化一次。当在一个成员初始化列表中同时出现对虚基类和非虚基类构造函数的调用时,虚基类的构造函数先于非虚基类的构造函数执行。例子程序:#includeusingnamespacestd;classBase{public:Base(chari){cout<<"Baseconstructor.--"<
7};classMyDerived:publicDerived1,publicDerived2{public:MyDerived(chari,charj,chark,charl,charm,charn,charx):Derived2(i,j),Derived1(k,l),Base(m),d(n){cout<<"MyDerivedconstructor.--"<usingnamespacestd;classA{public:intn;};classB:publicA{};//classB:virtualpublicA{};classC:publicA{};//classC:virtualpublicA{};classD:publicB,publicC{public:intgetn(){returnB::n;}};intmain()
8{Dd;d.B::n=10;d.C::n=20;cout<
分享到:
收藏