1、 下面关于类概念的描述中,___D_是错误的。
A.类是抽象数据类型的实现
B.类是具有共同行为的若干对象的统一描述体
C.类是创建对象的样板
D.类是C语言中的结构体类型
2、下列对重载函数的描述中,__A__是错误的。
A.重载函数中不允许使用默认参数
B.重载函数中编译是根据参数表进行选择//与返回值无关,只和函数入口有关
C.不要使用重载函数来描述毫无相干的函数
D.构造函数重载将会给初始化带来多种方式
3、有以下类的说明,请指出错误的地方。
Class sample
{
int a=2.5;//改为int a;
sample();
public:
sample(int val);
~sample();
};
4、有关析构函数的说法不正确的是_C___。
A、析构函数有且只有一个
B、析构函数无任何函数类型
C、析构函数和构造函数一样可以有形参
D、析构函数的作用是在对象被撤消时收回先前分配的内存空间
5、下列说法中正确的是___B_。
A.类定义中只能说明函数成员的函数头,不能定义函数体
B.类中的函数成员可以在类体中定义,也可以在类体之外定义
C.类中的函数成员在类体之外定义时必须要与类声明在同一文件中
D.在类体之外定义的函数成员不能操作该类的私有数据成员
6、下列定义中,sample是一个类,___B_是定义指向对象数组的指针P。
A. sample *p[5]
B. sample (*p)[5]
C. (sample *p)p[5]
D. sample *p[]
7、下列程序的执行结果是
Class sample
{
Public:
Sample(){cout<<”constructor”< }; Void fn(int i) { Staticsample c; Cout<<”i=”<
} Void main() { fn(10); fn(20); } -------- constructor i=10 i=20 8、改正下列程序中的错误 Class point { intx,y; public: point(intx,int y); }; Void main() { Pointdata(5,5); Cout< Cout< } ------ class point { public: point(int a,int b){x=a;y=b;} int x,y; }; int main() { point data(5,5); cout< cout< return 0; } 9、找出程序中的错误,并说明原因 Class sample { Public: Static voidf(sample my); Private: int n; }; Void sample::f() { Cout< } ------------- 静态成员函数不可以访问非静态成员。 10、阅读以下程序,找出错误的地方,并说明原因。 Class sample { intx,y,c; public: sample(inti=0,int j=0); void f() const; }; Voidsample::f() const { Cout< c++; } ------- Const函数不可以改变变量的值 11、若有: int i; int &j=i; i=5; j=i+1; 则i=___6_, j=__6__. 12、阅读以下程序,如果程序中有错误,找出错误,说明原因并改正,如没有错误,请写出运行结果。 #include int &add(int x,int y) { returnx+y; } Void main() { intn=2,m=10; cout<<(add(n,m)+=10)< } ------------- Return x+y 不是一个确切的变量,所以不能当做引用返回。 13、下面关于友元的描述中,错误的是(D) A.友元函数可以访问该类的私有数据成员 B.一个类的友元类中的成员函数都是这个类的友元函数 C.友元可以提高程序的运行效率 D.类与类之间的友元关系可以继承 14、下列关于class 与struct差别说法中,正确的是(A) A、class 成员缺省为私有的,而struct成员缺省为公有的; B、class 成员缺省为公有的,而struct成员缺省为私有的; C、class不能在内部定义函数,而struct可以在内部定义函数; D、class 可以在内部定义函数,而struct不能在内部定义函数; 15、友元运算符obj1>obj2被C++编译器解释为__C__。 A. obj2. operator>(obj1) B. obj1. operator>(obj2) C.operator>(obj1,obj2) D. >(obj1,obj2) 17、为了满足运算符“+”的可交换性,必须将其重载为__友元函数__。 //虽然将运算符重载为成员函数答案一样,但是函数在调用过程中所走的程序不同,而重载为友元函数只是参数的位置不同,并没有影响函数内部的走法。 18、#include”iostream.h” main() { int a[3][3]={1,3,6,2,4,8,5,7,9}; cout<<*(a[1]+1); } 则输出结果为: 4 19、函数重载、覆盖、隐藏的区别? (1) class FS{ double real, image; public: FS(double a=0,double b=0){real =a; image =b;} FS operator *(FS f) { FS g=*this; g.real= g.real*f.real- g.image*f.image; g.image= g.real* f.image+ g.image* f.real; return g; } };
下面我们从成员函数的角度来讲述重载和覆盖的区别:
重载的特征有:(“重复”、“重叠”)―――――――――――――――――(静态联编)
1) 相同的范围(在同一个类中);
2) 函数名字相同;
3) 参数不同;
4) 返回值可相同、可不同;
5) virtual关键字可有可无。
覆盖的特征有:(“使原来的失去效果”)―――――――――――――――(动态联编)
1) 不同的范围(分别位于派生类与基类);
2) 函数名字相同、参数列相同、返回值类型相同;
3) 只有函数体(花括号中的部分)不同;
4) 基类函数必须有virtual关键字。
//覆盖在用派生类地址赋值给基类指针时用得着,因为基类指针对自己所调用的函数有要求,所以要想展示动态联编的效果,那么派生类成员函数必须和基类成员函数一模一样,不然指针不会调用派生类函数(找不到可以覆盖原函数的函数)。
隐藏是指派生类的函数屏蔽了与其同名的基类函数,规则如下:―――――(静态联编)
1) 如果派生类的函数与基类的函数同名,但是参数不同。此时,不论有无virtual关键字,基类的函数将被隐藏(注意,不要与重载混淆)。
2) 如果派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有virtual关键字。此时,基类的函数被隐藏(注意,不要与覆盖混淆)。
隐藏与覆盖到底有什么区别?
在覆盖中,用基类指针和派生类指针调用函数f()时,系统都是执行的派生类函数f(),而非基类的f(),这样实际上就是完成的“接口”功能。
而在隐藏中,用基类指针和派生类指针调用函数f()时,系统会进行区分,基类指针调用时,系统执行基类的f(),而派生类指针调用时,系统“隐藏”了基类的f(),执行派生类的f(),这也就是“隐藏”的内在特点。
20、虚函数是动态联编的基础,虚函数一定是非static的成员函数。
当类中的一个成员函数被说明为虚函数,这就意味着该成员函数在派生类中可能有不同的定义。当使用这个成员函数操作指针或引用所标识的对象时,将对该成员函数调用采取动态联编方式;
动态联编只能通过指针或引用标识对象来操作虚函数,或者由成员函数调用虚函数。如果采用一般类型的标识对象来操作虚函数,则将采用静态联编方式调用虚函数。
下面看一个例子:
#include
class point
{
int x,y;
public:
point(int x1,int y1){x=x1;y=y1;}
virtual int area() const {return 2;}
};
class rect:public point
{
int l,w;
public:
rect(int x1,int y1,int l1,int w1):point(x1,y1)
{
l=l1;w=w1;
}
virtual int area() const {return l*w;}
};
void fun(point &p)
{
cout<
}
void main()
{
rect rec(2,4,10,6);
fun(rec);
}
输出结果应为多少?若将(point &p)改为(point p),结果如何?
60 2
21、关于动态联编的下列描述中,__D___是错误的。
A、动态联编是以虚函数为基础的
B、动态联编是在运行时确定所调用的函数代码
C、动态联编调用函数操作是指向对象的指针或对象引用
D、动态联编是在编译时确定操作函数的
22、对虚函数的调用___D__。
A、一定使用动态联编
B、必须使用动态联编
C、一定使用静态联编
D、不一定使用动态联编
//如果是对象调用虚函数,那么只会执行该对象所对应的函数,这个是确定的,所以此时是静态联编
23、关于纯虚函数和抽象类的描述中,___C__是错误的。
A、纯虚函数是一种特殊的虚函数,它没有具体的定义
B、抽象类指具有纯虚函数的类
C、一个基类中说明有纯虚函数,该基类的派生类一定不再是抽象类
D、抽象类只能作为基类来使用,其纯虚函数的定义由派生来给出
24、阅读程序,讨论程序的输出结果。
#include
class A
{
public:
virtual ~A(){cout<<"call A::~A()"<
};
class B:public A
{
char *buf;
public:
B(int i){buf=new char[i];}
virtual ~B()
{
delete []buf;
cout<<"call B::~B()"<
}
};
void fun(A *a)
{
delete a;
}
void main()
{
A *a=new B(10);
fun(a);
}
call B::~B()
call A::~A()
25、编程题:
(1)定义一个复数类,实部用real变量,虚部用image变量,且均为double型,要求:
①当创建对象时不传参数,则real,image均为0;当传入一个实部参数时,则real=传入参数,image=0;
②定义一个“*”(乘号)运算符重载,重载为成员函数,实现复数的乘法运算。
(2)定义一个抽象类Shape,其中有纯虚函数double area();由Shape再派生出Circle、Rectangle类, Circle类中有中
心点坐标为int x,y半径为double R,面积为double area() ;Rectangle类有长(long)与宽(wide), 面积为double
area() ,设计一个函数dispalyArea(),其功能为显示面积,其形参为Shape类指针,请编程实现动态联编计算面积
的多态性。
(2)
#include "iostream.h"
class Shape
{
public:
virtual double area()=0;
};
class Circle:public Shape
{
private:
int x,y;
double R;
public:
Circle(double r){R=r;}
double area()
{
return 3.1415*R*R;
}
};
class Rectangle:public Shape
{
private:
double Long,Wide;
public:
Rectangle(double x,doubley){Long=x;Wide=y;}
double area()
{
return Long*Wide;
}
};
void dispalyArea(Shape *S)
{
cout< } void main() { Circle C(2); Rectangle R(3,4); dispalyArea(&C); dispalyArea(&R); }
总结:
可以访问类中的私有数据成员的是:
1、类体的成员函数
2、类体的成员函数中的形参中的该类的对象、对象引用或者对象指针,以及函数体中定义的局部对象、对象引用或者对象指针。(1,2说明只要是在类的内部就可以,除了static,那是类级的概念)
3、类的友元函数中的形参中的该类的对象、对象引用或者对象指针,以及函数体中定义的局部对象、对象引用或者对象指针。(也就是在友元函数体内)
4、类的友元类的成员函数中形参中的该类的对象、对象引用或者对象指针,以及函数体中定义的局部对象、对象引用或者对象指针。(同样就是在友元函数体内,友元类的成员函数就是该类的友元函数)