一、选择题 1.下列关于对象初始化的叙述中,正确的是 A 定义对象的时候不能对对象进行初始化 B 定义对象之后可以显式地调用构造函数进行初始化 C 定义对象时将自动调用构造函数进行初始化 D 在一个类中必须显式地定义构造函数实现初始化 答案:C. (对象在定义时会自动调用构造函数进行初始化) 2.下列关于基类和派生类关系的叙述中,正确的是 A 每个类最多只能有一个直接基类 B 派生类中的成员可以访问基类中的任何成员 C 基类的构造函数必须在派生类的构造函数体中调用 D 派生类除了继承基类的成员,还可以定义新的成员 答案:D. 3.下列关于赋值运算符“=”重载的叙述中,正确的是 A 赋值运算符只能作为类的成员函数重载 B 默认的赋值运算符实现了“深层复制”功能 C 重载的赋值运算符函数有两个本类对象作为形参 D 如果己经定义了复制(拷贝 构造函数,就不能重载赋值运算符 答案:A 4.下列选项中,正确的C++标识符是 A 6_group B group~6 C age+3 D_group_6
答案:D 5. 下列循环语句中有语法错误的是 A int i;for( i=1;i<10;i++)cout<<‘*‘; B int i,j;for(i=1,j=0;i<10;i++,j++)cout<<‘*‘; C int i=0;for(;i<10;i++)cout<<‘*‘; D for(1)cout<<‘*‘; 答案:D. 其他三个都能正常运行 分号不能少 6. 下列定义语句中,错误的是 A intpx*; B char*acp[10]; Cchar(*pac)[10]; D int(*p)();
答案:A. A明显编译不过。 B定义了一个数组;C 定义了一个指针pac,它指向含有10个char型元素的数组首地址
D.定义了函数指针p,这个指针指向的函数无参数且返回一个int值 7. 若MyClass为一个类,执行“MyClass a[4],*p[5];”语句时会自动调用该类构造函数的次数是 A2 B5 C4 D 9
答案:C. a[4]定义了4个元素的数组,数组里存的是MyClass对象,故要调用默认的构造函数来初始化4个MyClass对象,
*p[5]定义了5个元素的数组,数组中存放的是指向MyClass对象的指针,故没有实例化MyClass对象 8. 有如下程序: #include<iostream> #include<cmath> usingstd::cout; classPoint{ public: frienddouble distance(const Point &p); //p距原点的距离 Point(int xx=0,int yy=0):x (xx),Y(YY){}//① private: Int x,Y; }; doubledistance(const Point &p) { //② returnsqrt(p.x*p.x+p.Y*p.Y); } int main(){ Point p1(3,4); cout<<distance(p1); //③ return 0; } 下列叙述中正确的是 A 程序编译正确 B 程序编译时语句①出错 C 程序编译时语句②出错 D程序编译时语句③出错 答案:A. 经过验证,程序编译正确。 9. 下列哪两个是等同的 int b; const int *a =&b; ‚ const * int a = &b; ƒ const int*const a = &b; „ int const* const a = &b; A „ B ‚ C ƒ„ ` D ‚ƒ 答案:3和4相同。 1定义一个指针a,它指向一个整型的不变量,即不能通过a来修改b的值(但b的值是可以修改的)
2编译错误。3和4均定义的指针它本身就不可改变(不能再把另外的变量地址赋值给它),它指向的变量也不可通过
它来修改。 10. 有如下语句序列: charstr[10];cin>>str; 当从键盘输入”I lovethis game”时,str中的字符串是 A"I love this game" B "I love thi" C"I love" D "I"
答案:D. cin读入数据遇到空格结束;并且丢弃空格符;缓冲区有残留数据,读入操作直接从缓冲区中取数据。 11. 有函数模板声明和一些变量定义如下: template<class Tl,class T2,class T3>T1 sum(T2,T3); doubledl,d2; 则下列调用中,错误的是 Asum<double,double,double>(dl,d2); B sum<double;double>(d1,d2); Csum<double>(d1,d2); D sum(d1,d2); 答案:D. D会导致编译错误,因为编译器无法去匹配参数列表 12. 以下程序段完全正确的是 A int*p; scanf("%d",&p); B int *p; scanf(“%d”,p); C int k,*p=&k; scanf("%d",p); D int k,*p:; *p= &k; scanf(“%d”,p);答案:A,C. A项编译能通过,也能运行,定义了一个指针p,并给这个指针赋值(输入的是地址)
B项中指针p的值没有定义,此时它没有指向任何内存地址,故通过它来给对应的内存地址输入
变量是错误的。C正确,通过p来给k赋值。D编译不过,语句*p=&k错误
13. 有定义语句:int *p[4];以下选项中与此语句等价的是 Aint p[4]; B int **p; C int *(p「4」); Dint (*p)「4」;
答案:C. D项定义了一个指针p,它指向有4个整型元素的数组。 14. 若要重载+、=、<<、=和[]运算符,则必须作为类成员重载的运算符是 A +和= B =和<< C ==和<< D =和[]
答案:D A中+可以为友元,B中<<可以为友元,C中==和<<均可以为友元
15. 下列说法正确的是( )
A 内联函数在运行时是将该函数的目标代码插入每个调用该函数的地方
B 内联函数在编译时是将该函数的目标代码插入每个调用该函数的地方
C 类的内联函数必须在类体内定义
D 类的内联函数必须在类体外通过加关键字inline定义
答案:B
只有inline这个关键字包含在函数声明中, 才是内联函数。 与类没有任何的关系!16. 下面对于友元函数描述正确的是( ) A 友元函数的实现必须在类的内部定义 B 友元函数是类的成员函数 C 友元函数破坏了类的封装性和隐藏性 D 友元函数不能访问类的私有成员答案:C
怎么实现运算符的重载?
方式:类的成员函数 或 友元函数(类外的普通函数)
规则:不能重载的运算符有 . 和 .* 和 ?: 和 :: 和 sizeof
友元函数和成员函数的使用场合:一般情况下,建议一元运算符使用成员函数,二元运算符使用友元函数
1、运算符的操作需要修改类对象的状态,则使用成员函数。如需要做左值操作数的运算符(如=,+=,++)
2、运算时,有数和对象的混合运算时,必须使用友元
3、二元运算符中,第一个操作数为非对象时,必须使用友元函数。如输入输出运算符<<和>>
17. 在公有派生情况下,有关派生类对象和基类对象的关系,下列叙述不正确的是( ) A 派生类的对象可以赋给基类的对象 B 派生类的对象可以初始化基类的引用 C 派生类的对象可以直接访问基类中的成员 D 派生类的对象的地址可以赋给指向基类的指针 答案:C. 其它都是多态的特性
18. 下列关于多态性的描述,错误的是( ) A C++语言的多态性分为编译时的多态性和运行时的多态性 B 编译时的多态性可通过函数重载实现 C 运行时的多态性可通过模板和虚函数实现 D 实现运行时多态性的机制称为动态绑定 答案:C. 模版是编译时的多态
19. 如果友元函数重载一个运算符时,其参数表中没有任何参数则说明该运算符是( ) A 一元运算符 B二元运算符 C 选项A 和选项B 都可能 D 重载错误
答案:D. C++中用友元函数重载运算符至少有一个参数,重载一目运算符要有一个参数,重载二目运算符要有两个参数
20. 在下列关于C++函数的叙述中,正确的是( )
A 每个函数至少要有一个参数 B 每个函数都必须返回一个值
C 函数在被调用之前必须先声明 D 函数不能自己调用自己
答案:C
21. 如果进栈序列为el,e2,e3,e4,则可能的出栈序列是 ( )
A e3,el,e4,e2 B e2,e4,e3,el C e3,e4,e1,e2 D 任意顺序
答案:B. 排除法
22. 下面关于模板的描述,错误的是 ( )
A 函数模板和类模板的参数可以是任意的数据类型
B 类模板不能直接使用,必须先实例化为相应的模板类.然后定义了模板类的对象
C 函数模板不能直接使用,需要实例化为模板函数后才能使用
D 类模板的成员函数都是模板函数
答案:A
参数不能是任意类型的,至少该有明确的类型,比如抽象类就不行。
D中可能有些疑惑:
类模版的成员函数有两种情况:
1。涉及模板参数T的一定是个函数模板;
2。 不涉及(形式上,函数体,参数表内没出现)模板参数T的也是个函数模板;
角度一:成员函数的类型中包含一个属性“属于什么类”,所以void A<T>::fun(){};这是就和T建立了联系,这时就能说明即使函数体内不涉及T类型,它也是个函数模板,因为由不同T类型,是不同的函数类型(因为域概念是成员函数类型的一部分)
23. 下面对静态数据成员的描述中,正确的是( )
A 静态数据成员可以在类体内进行初始化
B 静态数据成员不可以被类的对象调用
C 静态数据成员不能受private控制符的作用
D 静态数据成员可以直接用类名调用
答案:D
B明显不对。A其实有点歧义,一般来说静态成员是在类中声明,类外定义初始化,但当静态成员是const int时是
可以直接在类内部进行初始化的(此时还是要在类外部声明一下)
C也是有歧义的,静态变量的初始化时不受private作用,可以在类外进行初始化,但之后引用修改就不行了
24. 对类成员访问权限的控制,是通过设置成员的访问控制属性实现的,下列不是访问控制属性的是( )
A 公有类型 B私有类型 C 保护类型 D友元类型
答案:D
25.抽象基类是指( )
A 嵌套类 B 派生类 C含有纯虚函数 D 多继承类
答案:C
26.如果已定义了一个C++类CMyList并有以下语句:
CMyList list(3);
以下说法正确的是()。
A 该语句会创建一个CMyList类的一个对象;
B 该语句会创建一个CMyList类的3个对象;
C 必须为类CMyList定义一个构造函数;
D 必须为类CMyList定义一个析构函数;
E 必须定义函数CMyListlist(int);
答案:C.
必须定义参数为int类型的构造函数,否则编译不通过。
27. 以下说法正确的是( )。
A内联(inline)函数改善了函数调用的执行效率。
B类A的友元(friend)函数可以访问类A的私有成员。
C类A的友元(friend)类B可以访问类A的私有成员。
D类A的静态数据成员为类A的所有对象所共享。
E类A的静态成员函数没有传递this 指针作为参数。
答案:A,B,C,D,E
28.类B从类A派生,则类B可以访问类A中的( )成员。
A public成员 B private成员 Cprotected成员 D数据成员 E函数成员
答案:A,C
29. 面向对象的程序设计语言具有()等共同特性。
A封装性 B多态性 C简单性 D复杂性 E继承性
答案:A,B,E
30. 现有一个程序如下:
#i nclude
class A
{ public:
void f(){ cout<< “A::f()”;}
};
class B
{ public:
void f(){ cout<< “B:f()”;}void g(){ cout<< “B:g()”;}
};
class C : public A, public B
{ public:
void g(){cout<<”C::g()”;}
void h()
{cout<<”C::h()”;
f(); //语句1
}
};
void main()
{ C obj;
obj.f(); //语句2
obj.A::f();//语句3
obj.B::f();//语句4
obj.g(); //语句5
}
则编译时会产生错误的语句有()
A语句1 B语句2 C语句3 D语句4 E语句5
二、 填空题
1. int func(x)
{
int countx = 0;
while(x)
{
countx ++;
x = x&(x-1);
}
return countx;
}
假定x = 9999。 函数的运行结果为_____
2. 一个栈的初始状态为空。首先将元素5,4,3,2,1 依次入栈,然后退栈一次,再将元素A,B,C,D依次入栈,之后将所有元素全部退栈,则所有元素退栈(包括中间退栈的元素)的顺序为_______________。
3. 一棵二叉树有10个度为1的结点,7个度为2的结点,则该二叉树共有个__1_结点。
4. 一个双目运算符作为类的成员函数重载时,重载函数的参数表中有_1_个参数。
分析:作为类的成员函数时,会传入代表本对象的this指针,从而省去了一个参数
5. #defineDOUBLE(x) x+x ,i= 5*DOUBLE(5); i的值为_ _。6. switch()中不允许的数据类型是____。
除整型和字符型外的其他类型都不允许
7. 某32位系统下, C++程序void *p = malloc( 100 ); sizeof (p) = ____。
分析:32位机上,各种类型的指针均为4字节
8. int a = 4;(++a) += a;执行后a的值为_10_。
分析:先做a的自增,a值变为5(修改了内存地址中的值,等式两边均变为5),相加为10
(a++) +=a是不合法的,因为a已经做了自增,此时还要返回a原先的值,并要用这个值
和等号右边的a值(已经自增过了)做运算,自然不合法。
(++a) += a++ 执行完后,a值为11. 相当于再做一次自增
9. 派生类中的成员函数可以直接访问基类中的公有成员和__保护__成员。
10. C++语言的参数传递机制包括传值和____引用____两种。
三、 阅读题
1.写出函数Test的运行结果
voidTest(void){
char*str = (char *) malloc(100);
strcpy(str,“hello”);
free(str);
if(str!= NULL){
strcpy(str,“world”);
printf(str);
}
}
2.写出程序的运行结果
#include<iostream>
using namespace std;
class Base{
Int x;
Public:
Base(int b):x(b){}
virtual void display(){cout<<x;}
};
class Derived:public Base{
Int y;
public:
Derived(int d):Base(d),y(d){}
void display(){cout<<y;} };
int main(){
Base b(1);Derived d(2);
Base*p=&d;
b .display();d.display();p一>display();
return 0;
}
3.下面的函数实现在一个固定的数上加上一个数,有什么错误,改正
int add_n(int n) { static int i=100; i+=n; return i;
}
4.i最后等于多少?
int i = 1;int j = i++;
if((i>j++) && (i++ == j)) i+=j;
5.#include…
constint SIZE=10;
classstack
{char stck[SIZE];
inttop;
public:
voidinit();
voidpush(char ch);
charpop();
};
voidstack::init()
{top=0; }
voidstack:push(char ch)
{if(top==SIZE)
{ cout<<”Stack is full.\n”;
return ; }
stck[top++]=ch;
}
charstack:pop()
{if(top==0)
{ cout<<”Stack is empty.\n”;
return 0;}
return stck[--top];
}
voidmain()
{stack s1, s2;
s1.init();
s2.init();
s1.push(‘a’);
s1.push(‘b’);
s1.push(‘c’);
s2.push(‘x’);
s2.push(‘y’);
s2.push(‘z’);
for(int i=0; i<3; i++)
cout<<”Pop s1:”<< s1.pop();
for(i=0; i<3; i++)
cout<<”Pop s2:”<< s2.pop();
}
四、附加题:
写一个Singleton。Singleton模式主要作用是保证在Java应用程序中,一个类Class只有一个实例存在。
public class Singleton {
private static Singleton instance = null;
public static synchronized Singleton getInstance() {
//这个方法比上面有所改进,不用每次都进行生成对象,只是第一次
//使用时生成实例,提高了效率!
if (instance==null)
instance=new Singleton();
return instance;
}
}