石河子大学-信息学院-c++期末考试-复习题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
(小题前面那个复习题里面有,大题注意一下)
试题一
一、单项选择题(共20分,每题2分,正确答案只有一项)
1.以下说法中正确的是
A. 类A 的private成员只能在类A的成员函数内部进行直接访问,其他任何地方都不能直接访问。
B。
静态成员一定不能是private 的.
C。
在某种情况下,在派生类的成员函数内部也能对基类的私有成员进行直接访问。
D。
只有成员变量才能是protected的,成员函数不能是protected 的。
(C)
2.以下关于this 指针的说法中不正确的是:
A. const成员函数内部不可以使用this 指针
B。
成员函数内的this 指针,指向成员函数所作用的对象.
C. 在构造函数内部可以使用this指针
D。
在析构函数内部可以使用this 指针
(A)
3.下列类模板中定义正确的是:
A。
template<class T1,class T2>
class A : {
T1 b;
int fun(int a ){return T1+T2;}};
B。
template<class T1,class T2>
class A {
int T2;
T1 fun(T2 a ){return a + T2;} };
C。
template<class T1,class T2〉
class A {
public:
T2 b; T1 a;
A<T1>(){}
T1 fun() {return a; }
};
D。
template<class T1,class T2>
class A {
T2 b;
T1 fun(double a ){b = (T2) a; return (T1)a; }
};
(D)
4.假设p1,p2 是STL中的list 容器上的迭代器,那么
以下语句哪个是不符合语法的
A. p1 ++ ;
B。
p1 -—;
C。
p1 += 1;
D. int n = (p1 == p2 );(C)
5.将一个对象放入STL中的容器里时:
A。
实际上被放入的是该对象的一个拷贝(副本)
B. 实际上被放入的是该对象的指针
C 实际上被放入的是该对象的引用
D。
实际上被放入的就是该对象自身
(A)
6.以下关于函数对象的说法正确的是:
A。
函数对象所属的类将()运算符重载为一个成员函数
B. 函数对象所属的类将[]运算符重载为一个成员函数
C. 函数对象所属的类不能有成员变量
D。
A 和C都对
(A)
7. 以下说法正确的是:
A.const成员函数内可以调用非const成员函数
B.在抽象类的某些成员函数中,可以出现调用纯虚函数
的语句
C.静态成员函数也可以是虚函数
D.静态成员变量只能通过静态成员函数来访问
(B)
8. 如果将运算符“ * " 重载为某个类的成员运算符(也即成员函数),则该成员函数的参数个数是:
A.0 个
B. 1个
C. 2个
D. 根据实际作用不
同,0个或1个都行
(D)
9. 以下关于STL 中stack 类模板的正确说法是:
A. stack 是关联容器
B。
对于stack 上的迭代器p,能够执行p++ 操作
C. stack 可以用deque实现
D。
可以用sort 算法对stack 进行排序
(C)
10. 以下说法正确的是
A. 在静态成员函数中调用虚函数是动态联编(多态) B。
在构造函数中调用虚函数,不是动态联编
C. 抽象类的成员函数都是纯虚函数
D。
构造函数和析构函数都不能是虚函数
(B)
二.以下程序编译、连接都能通过,请写出运行时输出的结果。
你认为没有输出的,就写"无输出”(共28分)。
1)4分
#include 〈vector〉
#include 〈iostream>
using namespace std;
class A {
private :
int nId;
public:
A(int n){
nId = n;
cout 〈< nId 〈< " contructor” 〈〈endl;
};
~A(){
cout 〈〈nId 〈< ” destructor” 〈〈endl;
}
};
main()
{
vector〈A*〉vp;
vp。
push_back(new A(1));
vp。
push_back(new A(2));
vp。
clear();
A a(4);
}
/*
1 contructor
2 contructor
4 contructor
4 destructor
*/
2)4分
#include <iostream。
h〉
class Apple {
private :
static int nTotalNumber;
public:
Apple()
{ nTotalNumber ++; }
~Apple( ) { nTotalNumber —-;}
static void PrintTotal()
{ cout 〈< nTotalNumber <〈endl;} };
int Apple::nTotalNumber = 0;
int main () {
Apple *p = new Apple[4];
Apple::PrintTotal();
Apple p1,p2;
delete []p;
Apple::PrintTotal();
}
/*
4
2
*/
3)4 分
#include 〈iostream〉
#include 〈vector>
using namespace std;class A {
public:
int i;
A( int n):i(n){};
void Print() { cout 〈〈i 〈〈",”; }
};
A &Func(vector<A〉&v, A * p)
{
v.push_back (* p);
for( int i = 0;i < v。
size(); i ++)
if(v[i]。
i == 2 ) {
p = & (v[i]);
break;
}
return *p;
}
main()
{
const int SIZE = 4;
A array[SIZE]= { A(1),A(2),A(3),A(4)};
vector〈A〉v(array,array + SIZE);
A *p = new A(5);
Func(v,p) = 10;
for( int i = 0;i < v.size(); i ++)
v[i]。
Print();
cout 〈< endl;
cout <〈p—〉i;
}
/*
1,10,3,4,5,
5
*/
4)4 分
#include 〈iostream。
h〉
class A {
public:
A( ){ }
virtual void func()
{ cout 〈〈”A::func” 〈< endl; }
~A(){}
virtual void fund()
{cout <〈”A::fund" 〈〈endl;}
};
class B:public A {
public:
B () { func();}
void fun(){func( );}
virtual ~B (){ fund( );}
};
class C :public B {
public :
C(){ }
void func()
{cout <〈"C::func" 〈〈endl; }
~C() {fund();}
void fund()
{cout 〈< ”C::fund” 〈< endl;}
};
main()
{
A * pa = new C();
delete pa;
B * pb = new C();
delete pb;
}
/*
A::func
A::func
C::fund
A::fund
*/
5)4分
#include 〈iostream。
h〉
#include 〈vector>
#include 〈numeric>
using std::vector;
using std::accumulate ;
class Complex {
double real;
double image;
public:
Complex(double r = 0, double i = 0):real(r),image(i){ }
friend Complex operator+(const Complex &c ,int i);
friend ostream & operator<〈(ostream &o,const Complex & c);
};
Complex operator+(const Complex & c ,int i)
{
Complex tmp;
tmp。
real = i *i + c。
real;
tmp.image = c.image;
return tmp;
}
ostream &operator〈〈(ostream &o,const Complex & c)
{
o 〈< c。
real <〈"+” 〈〈c.image 〈< "i” ;
return o;
}
main()
{
int a[]= { 1,2,3,4 };
vector〈int〉v(a,a+4);
cout 〈〈accumulate(v。
begin(),v。
end (),Complex(2,3));
}
/*
32+3i
*/ 6)4分
#include 〈iostream>
#include <map〉
using namespace std;
class Gt
{
public:
bool operator()(const int &n1,const int & n2)const {
return ( n1 % 10 ) > (n2 %10);
}
};
int main() {
typedef map<int,double,Gt> mmid;
mmid MyMap;
cout <〈MyMap。
count(15) 〈< endl;
MyMap。
insert(mmid::value_type(15,2。
7));
MyMap。
insert(mmid::value_type(15,99.3));
cout <〈MyMap。
count(15)<< endl;
MyMap.insert(mmid::value_type(30,111.11));
MyMap.insert(mmid::value_type(11,22.22));
cout 〈〈MyMap[16]〈〈endl;
for(mmid::const_iterator i = MyMap.begin();
i != MyMap。
end();i ++ )
cout 〈< "(" 〈< i—>first 〈< ”,” 〈〈i-〉second 〈〈”)" <〈”,”;
}
/*
1
(16,0),(15,2。
7),(11,22。
22),(30,111.11)
*/
7)4 分
#include 〈iostream.h〉
class A1 {
public:
int i;
A1(int n):i(n) {cout 〈〈”A1_Con:” 〈< i 〈〈endl;}
~A1(){ cout 〈< "A1_Des:” <〈i <〈endl; }};
class A2 {
public:
int i;
A2(int n):i(n){cout 〈< ”A2_Con:" << i <〈endl;}
~A2(){cout <〈"A2_Des:” 〈〈i 〈〈endl;} };
class B {
public:
B(){cout <〈"B_Con” 〈〈endl;}
~B(){ cout << "B_Des” <〈endl;}
};
class C:public B {
public:
A2 a2;
A1 a1;
C():a1(1),a2(1) { cout <〈”C_Con” 〈〈endl;}~C(){cout 〈< ”C_Des” <〈endl;}
};
main(){
C *pc = new C;
}
/*
B_Con
A2_Con:1
A1_Con:1
C_Con
*/
三、程序填空(36分):
已知以下程序的输出结果,请填出缺少的部分。
您填写的内容里不能包含分号。
假设您需要的头文件前面都已经有#include 语句包含进来了(即可以随意使用标准库中的类、模板等)
1) 6分
void OutputN(int n);
函数的功能是输出所有数正整数i,j,k 的组合,该组合满足下列3个条件:
1) i,j,k都不大于n
2)i〈j<k
3)i+j+k能够被3整除
比如,OutputN(5)的输出结果就是:
1,2,3
1,3,5
2,3,4
3,4,5
请补上丢失的部分。
#include <iostream.h>
void OutputN( int n)
{
int i,j, k;
for( _____;______;_____)
for( _____ ;______;______ )
for( ______ ;______; ______ )
if( ( i + j + k) % 3 == 0 )
cout 〈< i << ”," << j << "," 〈< k 〈< endl;
}
/*
i = 1
i 〈= n
i ++
j = i + 1
j 〈= n
j ++
k = j + 1
k<= n k++
*/
2)6分
从1,2,3,4,5这5个整数中取一个或多个数(每个数最多只能取1次),使得取出的数总和能被3整除.
下面的这段程序的功能就是用枚举的办法,求出了所有满足条件的取法并输出.输出结果如下:
1,2,
3,
1,2,3,
2,4,
2,3,4,
1,5,
1,3,5,
4,5,
1,2,4,5,
3,4,5,
1,2,3,4,5,
请填出缺少的部分
#include 〈vector〉
#include 〈iostream>
#include <algorithm>
using namespace std;
int bit(int n,int b)
{
return ____________;
}
main()
{
int i;
int sum;
vector<int〉v;
for(i = 1;i < 32;i ++ ){
sum = 0;
____________;
for( int j = 0;j 〈5;j ++ )
if(bit( __________)){
sum += j + 1;
v.push_back (j+1);
}
if( (sum %3) == 0 ){
for( int k = 0;k 〈v。
size();k ++)
cout <〈v[k] <〈",”;
cout << endl;
}
}
}
/*
n &(1 <〈b)
v。
clear();
i,j
*/
3) 6分
输出结果:
Tom,Jack,Mary,John,
程序:
#include 〈vector>
#include <iostream〉
#include <string>
using namespace std;
template <class T>
class MyClass
{
vector〈T〉array;
public:
MyClass _____________________
{
copy(begin, begin + n,array。
begin());
}
void List(){
______________________;
for(i = array。
begin(); i != array。
end();i ++)
cout << *i << ”,” ;
}
};
main()
{
string array[4] = {"Tom”,”Jack",”Mary”,”John"};
_________________________;
obj.List();
}
/*
( T * begin,int n ):array(n)
vector<T〉::iterator i
MyClass<string〉obj(array,4)
*/
4) 6 分
输出结果:
A::Print: 1
B::Print:2
B::Print: 3
程序:
template 〈class T〉
void PrintAll(const T &c )
{
T::const_iterator i;
for(i = c.begin();i != c.end(); i ++ )
_________________;
};
class A {
protected:
int nVal;
public:
A(int i):nVal(i) {}
virtual void Print(){cout 〈< ”A::Print:” 〈〈nVal <〈endl;}};
class B:public A {
public:
B(int i):A(i){ }
void Print(){cout 〈〈"B::Print: ” 〈< nVal 〈〈endl;}
};
main()
{
__________________;
v.push_back( new A(1));
v.push_back (new B(2));
v.push_back (new B(3));
PrintAll(v);
}
/*
( *i ) —〉Print()
vector<A *〉v
*/
5) 6分
回文串指的是颠倒过来后还是与原串一样的字符串。
比如“abba”,“bcd232dcb”,都是回文串。
下面的程序运行后等待输入一串字符(字符个数小于4000),敲回车后程序判断输入的字符串是否是回文串,如果是,输出yes,否则,输出no。
比如输入
abba (回车)
则输出
yes
输入
abcd (回车)
则输出:
no
请填空。
#include 〈string。
h〉
#include 〈iostream.h〉
char szWord[5000];
bool Palindrome(char *s,int nLen )
{
if(___________)
return true;
if(____________)
return false;
return Palindrome(___________);
}
main()
{
cin.getline(szWord, 4990);
if(Palindrome(szWord,strlen(szWord)))
cout << ”yes" ;
else
cout 〈< ”no”;
}
/*
nLen <= 1
s[0] != s[nLen—1]
s+1,nLen-2
*/
6)6分
输出结果是:
5
程序:
class A {
public:
int val;
A(____________ ){ val = n;};//(a)
___________ GetObj() {// (b)
return _________;// (c)
}
};
main() {
A a;
cout 〈〈a。
val 〈< endl;
a。
GetObj()= 5;
cout 〈< a。
val <〈endl;
}
/*
int n
A &
*this
*/
四、编程题
1. ( 8分)程序员马克斯的程序风格和他的性格一样怪异.很不幸他被开除后老板命令你接替他的工作.马克斯走之前分愤然删除了他写的一个类模板MyMax中的代码,你只好将其补出来。
你只知道MyMax模板的作用与求数组或向量中的最大元素有关,而且下面程序的输出结果是:
5
136
请补出马克斯删掉的那部分代码。
该部分代码全部位于"//开头" 和"//结尾”之间,别处一个字节也没有。
By the way,马克在空白处留下了以下三个条件:
1)不准使用除true 和false 以外的任何常量,并且不得假设true的值是1或任何值
2)不得使用任何库函数或库模板(包括容器和算法)
3)不得使用static 关键字
你不想表现得不如马克斯,所以你只好遵守这三个条件。
#include <vector〉
#include 〈iostream〉#include 〈algorithm〉
using namespace std;
template 〈class T>
class MyMax
{
//开头
……
//结尾
};
class A {
public:
int i;
A(int n) :i(n) {};
A(){};
};
bool operator 〈(const A &a1,const A & a2)
{
return a1。
i < a2。
i ;
}
ostream &operator<〈( ostream & o, const A &a)
{
o 〈< a。
i;
return o;
}
main()
{
A a[5]= {A(1),A(5),A(3),A(4),A(2)};
int b[9]= {1,5,30,40,2,136,80,20,6};
int nMax; A aMax;
MyMax〈A〉outputa( &aMax);
copy(a,a+5,outputa);
cout 〈< outputa()〈< endl;
MyMax<int〉output(& nMax);
copy(b,b+9,output);
cout <〈output() 〈〈endl;
}
/*答案
public:
T * pMax;
bool bFirst;
MyMax〈T〉(T * p):bFirst(true),pMax(p) {};
MyMax〈T〉&operator *(){return * this; }
void operator ++(){}
void operator = (T &obj) {
if(bFirst){
*pMax = obj;
bFirst = false;
}
else {
if(* pMax 〈obj )
*pMax = obj;
}
}
T operator() (){
return *pMax;
}
*/
2. (8分)
CLinkList是一个带表头节点的单链表的类模板.带表头节点的单链表的特点是:当链表为空时,表中仍有一个节点,即表头节点.请完整写出CLinkList类模板的各个成员函数,使得下面程序的输出结果是:
0,1,2,3,
0,1,2,3,9,10,11,
注意:
1)不得调用任何库函数,库模板,不得使用static关键字,不得使用除NULL 以外的任何常量
2)不得为Node和CLinkList模板添加任何成员
3)不得添加任何全局变量,不得添加其他函数
#include <iostream。
h〉
template 〈class D〉
class Node {
public:
D data;
Node *next;
};
template<class D〉
class CLinkList
{
private:
Node<D> * pHead;
public:
CLinkList();
void AppendNode(D data);
void PrintList();
};
main()
{
CLinkList<int〉l;
for( int i = 0;i < 4;i ++)
l.AppendNode(i);
l.PrintList();
cout 〈〈endl;
for(i = 9;i < 12;i ++)
l.AppendNode(i);
l。
PrintList();
}
/*答案
template〈class D>
CLinkList〈D〉::CLinkList(){
pHead = new Node〈D〉;
pHead-〉next = NULL;
};
template 〈class D>
void CLinkList〈D>::AppendNode(D data)
{
Node<D〉* p = pHead;
while( p—〉next )
p = p—〉next;
p—〉next = new Node〈D>;
p—〉next—>data = data;
p-〉next—〉next = NULL;
}
template〈class D〉
void CLinkList<D〉::PrintList()
{
Node<D〉* p;
p = pHead—>next;
while(p ) {
cout <〈p-〉data 〈< ”,”;
p = p—〉next;
}
}
*/
试题二
一、单项选择题(共20分,每题2分,正确答案只有一
项)
7.抽象类
A。
至少含有一个纯虚函数
B. 至少含有一个静态函数
C. 其派生类必须提供纯虚函数的实现代码
D. 可以定义抽象类的对象,也可以由派生类生成新类(A)
8.以下说法中正确的是:
A.一个类可以有不止一个复制构造函数
B。
构造函数的返回值类型是void
C。
一个类只能定义一个析构函数,但可以定义多个构造函数
D. 一个类只能定义一个构造函数,但可以定义
多个析构函数
(C)
9.下列函数模板中定义正确的是:
A. template〈class T1,class T2〉
T1 fun (T1,T2) {return T1 + T2;}
B. template< class T>
T fun(T a){return T + a;}
a)tempmlate〈class T1,class T2〉
T1 fun(T1,T2){ return T1 + T2 ;}
b)template〈class T>
T fun(T a,T b){return a + b ; }
(D)
10.如果类定义中没有使用private、protected、或public
关键字,则所有成员
A. 都是public 成员B。
都是proctected 成员C。
都是private 成员 D. 不一定
(C)
11.对于通过new 运算符生成的对象
A。
在程序结束时自动析构
B。
执行delete 操作时才能析构
C。
在包含该new 语句的函数返回时自动析构
D。
在执行delete 操作时会析构,如果没有执行delete 操作,则在程序结束时自动析构
(B)
12.如果某函数的返回值是个对象,则该函数被调用时,
返回的对象
A. 是通过复制构造函数初始化的
B. 是通过无参数的构造函数初始化的
C. 用哪个构造函数初始化取决于函数中return 语句是怎么写的
D. 不需要初始化
(A)
7。
以下说法正确的是:
E.在静态成员函数中可以调用同类的其他任何成员函
数
F.const成员函数不能作用于非const 对象
G.在静态成员函数中不能使用this 指针
H.在纯虚函数中可以调用同类的其他非虚函数
(C)
8. 如果将运算符“[]”重载为某个类的成员运算符(也即成员函数),则该成员函数的参数个数是:
i.0 个B。
1个C。
2个D。
3
个
(B)
9。
编译器根据类模板,在需要的时候能自动生成:
A.一个或多个相似的函数
B.一个或多个函数模板
C.一个或多个对象
D.一个或多个相似的类
(D)
10。
以下说法不正确的是(假设在公有派生情况下)A。
可以将基类对象赋值给派生类对象
B。
可以将派生类对象的地址赋值给基类指针
C. 可以将派生类对象赋值给基类的引用
E.可以将派生类对象赋值给基类对象(A)
二.以下程序编译、连接都能通过,请写出运行时输出的结果.你认为没有输出的,就写”无输出"(共50分).
1)(5分)
int a;
class CA {
private :
int a;
public:
void SetA() { a = 10; }
CA(int i) { a = i;}
int GetA() {return ::a;}
};
int main (){
int a;
a = 15; ::a = 2;
cout 〈〈::a <〈",”〈〈a <〈endl;
CA objCA(100); objCA。
SetA ();
cout <〈::a <〈",”<<a <〈",” 〈<
objCA。
GetA() 〈〈endl; }
//2,15
//2,15,2
2)(5分)
int g = 10;
int SetValue1(int n)
{ n = 10;return n; }
int &SetValue2(int & n )
{n = 20; return n; }
main(){
int &ref = g;
ref = 100; SetValue1(ref );
cout 〈< g <〈",”; SetValue2(ref);
cout 〈< g 〈〈",";SetValue2(g) = 300;
cout 〈〈g <〈”,” ; int const c = 70;
ref = c;ref = 15;
cout <〈ref 〈〈”,” <〈c;
}
//100,20,300,15,70
3)(4分)
class CSample {
int x;
public:
CSample(){cout << ”C1” 〈〈endl;} CSample(int n ){
x = n;
cout 〈< ”C2,x=” 〈〈n << endl;}
};
main(){
CSample array1[2];
CSample array2[2]= {6,8};
CSample array3[2]= {12};
CSample * array4 = new CSample[3];
}
//C1
//C1
//C2,x=6
//C2,x=8
//C2,x=12
//C1
//C1
//C1
//C1
4)(8分)
class Demo {
int id;
public:
Demo(int i)
{id = i;
cout 〈〈"id=" 〈〈id <〈”,Con” 〈〈endl; }~Demo()
{ cout << ”id=" 〈〈id 〈〈”,Des” 〈<endl; }};
Demo d1(4);
void fun(Demo d) {
static Demo d2(2);
Demo d3(3);
cout 〈〈"fun” 〈< endl;
}
void main () {
cout 〈<"main”〈〈endl;
fun(d1);
cout <〈”endmain" 〈< endl;
fun(d1);Demo *p = new Demo(8);}
/*
id=4,Con
main
id=2,Con
id=3,Con
fun
id=3,Des
id=4,Des
endmain
id=3,Con
fun
id=3,Des
id=4,Des
id=8,Con
id=2,Des
id=4,Des
*/
5)(4分)
class B {
private:
int nBVal;
public:
void Print()
{cout << ”nBVal=”〈〈nBVal <〈endl; }void Fun()
{cout 〈< ”B::Fun" 〈< endl; }
B (int n )
{nBVal = n;}
};
class D:public B {
private :
int nDVal;
public:
void Print(){
B::Print();
cout 〈< ”nDVal=”〈<nDVal〈〈endl;
}
D(int n): B(3*n)
{ nDVal = n;}
void Fun()
{cout <〈"D::Fun" 〈< endl;}
};
main(){
B * pb; D *pd;
D d(4);d。
Fun();
pb = new B(2); pd = new D(8);
pb -> Fun();pd—>Fun();
pb->Print (); pd—〉Print ();
pb = & d;pb—〉Fun();
pb—>Print();
}
/*
D::Fun
B::Fun
D::Fun
nBVal=2
nBVal=24
nDVal=8
B::Fun
nBVal=12
*/
6)(4分)
class Base {
public:
int val;
Base()
{cout 〈< "Base Constructor" 〈〈endl; }
~Base()
{ cout <〈”Base Destructor” << endl;}};
class Base1:virtual public Base { };
class Base2:virtual public Base {};
class Derived:public Base1, public Base2 {};main()
{ Derived d;}
/*
Base constructor
Base destructor
*/
7)(5分)
class A {
public:
A(){}
virtual void func()
{cout 〈< ”A::func” <〈endl;}
~A() {}
virtual void fund()
{cout 〈< "A::fund" 〈〈endl; }
};
class B:public A {
public:
B ( ){ func();}
void fun() {func( );}
~B ( ) {fund();}
};
class C :public B {
public :
C( ) {}
void func()
{cout 〈< ”C::func” <〈endl;}
~C() { fund();}
void fund()
{ cout << "C::fund” << endl;}
};
main()
{ C c; }
/*
A::func
C::fund
A::fund
*/
8)(5分)
template <class T>
T Max(T a,T b) {
cout 〈〈"TemplateMax” 〈<endl;
return 0;}
double Max(double a,double b)
{cout 〈〈"MyMax" 〈< endl;
return 0;}
main() {
int i=4,j=5;
Max( 1。
2,3.4);Max(i,j);}
//MyMax
//TemplateMax
9)(5分)
#include 〈iostream。
h>
class Apple {
private :
int nWeight;
static int nTotalNumber;
public:
Apple()
{nTotalNumber ++; }
~Apple(){nTotalNumber —-; }
static void PrintTotal()
{ cout <〈nTotalNumber 〈〈endl;} };
int Apple::nTotalNumber = 0;Apple Fun( Apple a )
{ a。
PrintTotal();return a ; }
int main (){
Apple p1,p2;
Apple *p = new Apple[3];
Fun(p1);p1。
PrintTotal(); }
//5
//3
12)(5分)
#include 〈iostream。
h〉
class A {
public :
virtual ~A(){cout<〈"DestructA” <<endl;}};
class B:public A {
public:
virtual ~B(){cout<〈”DestructB” <〈endl; }
};
class C:public B {
public:
~C(){cout 〈< "DestructC” 〈〈endl; }
};
void main() {
A * pa = new C;
delete pa; A a;
}
//DestructC
//DestructB
//DestructA
//DestructA
三、程序填空(共20分):
已知以下程序的输出结果,请填出缺少的部分。
您填写的内容里不能包含分号。
1)(6分)下面程序输出结果是:
5
请补足程序:
class A {
public:
int val;
A(____________ ){val = n; };//(a)
___________ GetObj() { // (b)
return _________;// (c)
}
};
main() {
A a;
cout 〈<a.val 〈〈endl;
a.GetObj()= 5;
cout <〈a.val 〈< endl;
}
//int n
//A &
//* this
2)(4分)下面程序的输出结果是:
A::Fun
C::Do
请补足横线上丢失的部分(4分)
#include 〈iostream.h〉
class A {
private:
int nVal;
public:
void Fun()
{cout 〈〈”A::Fun” 〈〈endl; };
void Do()
{cout <〈"A::Do" <〈endl;} };
class B:public A {
public:
virtual void Do()
{ cout 〈〈”B::Do" 〈〈endl;}};
class C:public B {
public:
void Do( )
{cout <〈"C::Do"<〈endl; }
void Fun()
{cout <〈"C::Fun” 〈< endl; }
};
void Call(___________ ) {
p。
Fun(); p.Do();
}
main(){
C c;
Call( c);
}
//B & p;
4)(6分)
填空使程序能编译通过,并写出运行的输出结果
#include 〈iostream.h〉
template 〈_____________> //(a)
class myclass {
T i;
public:
myclass (T a)
{i = a; }
void show()
{ cout 〈< i <〈endl;}
};
void main(){
myclass<________〉obj(”This”);//(b)
obj.show();
}
该程序输出结果为:________________ //(c)
//class T
// char *
//This
5)4分下面程序输出的结果是
4,6
请补出丢失的部分(5分):
class A {
int val;
public:
A(int n) {val = n;}
int GetVal(){return val;}
};
class B: public A {
private:
int val;
public:
B(int n):______________{}
int GetVal() {return val;}
}
main() {
B b1(2);
cout〈<b1。
GetVal()〈〈”,” 〈〈b1.A::GetVal()<〈endl;
}
/*
val(4),A(6)
答案不唯一
*/
四、编程题(共10分)
1)(5分)
下面的MyInt类只有一个成员变量.MyInt类内部的部分代码被隐藏了。
假设下面的程序能编译通过,且输出结果是:
4,1
请写出被隐藏的部分。
(您写的内容必须是能全部放进MyInt类内部的,MyInt的成员函数里不允许使用静态变量).
#include 〈iostream。
h〉
class MyInt
{
int nVal;
public:
MyInt( int n){nVal = n ;}
int ReturnVal(){ return nVal;}
………………….
};
main () {
MyInt objInt(10);
objInt—2—1-3;
cout <〈objInt.ReturnVal();
cout 〈<”,”;
objInt—2—1;
cout 〈〈objInt。
ReturnVal();
}
/*
MyInt &operator -(int x){
nVal -= x;
return *this;
}
*/
2)(5分)下面程序的输出结果是:
destructor B
destructor A
请完整写出class A。
限制条件:不得为class A 编写构造函数
#include 〈iostream。
h>
class A
{
………
};
class B:public A {
public:
~B(){cout 〈〈”destructor B” 〈〈endl;} };
main()
{
A *pa;
pa = new B;
delete pa;
}
/*
class A {
public:
virtual ~A(){cout 〈〈”destructor A” 〈< endl;}
};
*/
程序运行专项题
《1》
#include<iostream〉
using namespace std;
class classa{
public:
classa(){cout〈〈”基类\n”;}
};
class classb:public classa{
public:
classb(){cout〈〈"派生类\n”;}
};
void main(){
classb x;
cout〈〈”结束\n";
}
执行结果:
基类
派生类
结束
《2》
#include<iostream〉using namespace std;
class classa{
public:
~classa(){cout〈<”基类\n”;}
};
class classb:public classa{
public:
~classb(){cout〈〈”派生类\n”;}
};
void main(){
classb x;
cout<<"结束\n”;
}
执行结果:
结束
派生类
基类
《3》静态对象只创建一次,直到程序结束
#include〈iostream>
using namespace std;
class name{
public:
int a;
name(int i):a(i){cout〈〈”创建\n”;}
~name(){cout<〈”释放\n”;}
};
void f(int i){
static name c(i);
cout〈〈”i="<<i<〈",c.a="<〈c.a〈<endl; }
void main(){
f(5);f(10);
cout〈〈”结束\n";
}
执行结果:
创建
i=5,c.a=5
i=10,c.a=5
结束
释放
《4》
#include〈iostream〉
using namespace std;
class name{
int i;static int j;
public:
name(int x=0){i=x;j++;}
void display(){
cout〈〈”i=”〈<i〈<”,j="<〈j〈〈endl;
}
};
int name::j=0;
void main(){
name a,b;
a.display();
b.display();
}
执行结果:
i=0,j=2
i=0,j=2
《5》
#include<iostream>
using namespace std;
class A{
public:
A(int i){cout<〈”A:”〈〈i<<endl;}
};
class B{
public:
B(int i){cout〈<”B:”<<i<<endl;}
};
class C{
public:
C(){cout〈〈”C:—”〈〈endl;}
};
class D:public B,public A,public C{
B member;
public:
D(int a,int b,int c):A(a),member(c),B(b){}};
void main(){
D obj(1,2,3);
}
执行结果:
B:2
A:1
C:-
B:3
《6》—1派生类对象或指针可以复制,赋值,传递给基类对象,静态多态时,基类对象只能调用基类成员.
#include〈iostream>
using namespace std;
class A{
public:
void show(){cout<〈”A\n”;}
};
class B:public A{
public:
void show(){cout〈〈”B\n”;}
};
class C:public B{
public:
void show(){cout〈〈”C\n";}
};
void f(A *p){p—〉show();}
void g(A &x){x。
show();}
void main(){
A *p;
B b;
C c;p=&c;
f(&b);g(b);f(p);p->show();}
执行结果:
A
A
A
A
《6》-2
#include<iostream〉
using namespace std;
class A{
public:
virtual void show(){cout〈<”A\n";}
};
class B:public A{
public:
void show(){cout〈〈”B\n";}
};
class C:public B{
public:
void show(){cout<〈”C\n”;}
};
void f(A *p){p—〉show();}
void g(A &x){x。
show();}
void main(){
A *p;
B b;
C c;p=&c;
f(&b);g(b);f(p);p—>show();
}
执行结果:
B
B
C
C
《7》全局对象在执行主函数前创建,静态对象只创建一次,他们均在程序结束时释放.
#include〈iostream〉
using namespace std;
class name{
int a;
public:
name(int i){cout〈<"a="〈<(a=i)<〈endl;}
};
name b(3);
void f(){
static name c(2);
}
void main(){
cout<〈”开始”〈〈endl;
f();
cout<〈"结束"〈〈endl;
f();
name *p=new name(5);
}
执行结果:
a=3
开始
a=2
结束
a=5
《8》
#include〈iostream>
using namespace std;
class A{
protected:int x;
public:
A(int a=2){x=a;}
};
class B:public A{
int y;
public:
B(int b=3){y=b;}
B(int a,int b):A(a){y=b;}
void show(){cout〈〈x〈〈"”<<y〈〈endl;}
};
void main(){
B a;a。
show();
B b(4);b。
show();
B c(5,6);c.show();
}
执行结果:
2 3
2 3
5 6
《9》
#include〈iostream〉
using namespace std;
class A{
public:
virtual void show(){cout〈〈"A\n”;}
};
class B:public A{
public:
void show(){cout〈〈”B\n";}
};
class C:public B{
public:
void show(){cout<〈"C\n";}
};
void main(){
A a,*p;
B b,*q;
C *r,c;p=&a;q=&b;r=&c;
p—〉show();q->show();r-〉show();
p=q;p—>show();p=r;p—〉show();q=r;r—〉show();
}
执行结果:
A
B
C
B
C
C
《10》
#include<iostream〉
using namespace std;
class B{
int a;
public:
B(int i){a=i;}
void show(){cout<〈”a=”〈〈a<〈endl;}
};
class A{
B c;
public:
A(int i):c(i){}
void show(){c。
show();}
};
void main(){
A m(3);m。
show();
}
执行结果:
a=3
知识点
第7章结构体
7.1 定义结构体的一般语句格式和功能为:
格式 struct 标识符{成员表}变量表;
功能指定结构体的类型名和成员(即结构),并定义指定的结构体变量。
上述成员表为一组定义变量的语句,这些变量称作该结构体的成员,又称数据项、分量、域等。
上述“标识符"和结构体“变量表”可缺省,因此,定义结构体的语句格式可细分为四种。
7。
2 结构体中非指针型成员的数据类型必须是已存在的类型,指针型成员的基类型可放宽为自身或其后定义的类型。
7.3 结构体类型的数据占用连续内存,依次存储成员,整体存储量为其成员的存储量之和。
7.4 定义结构体变量的一般格式为:struct 标识符变量表;
在C++中,结构体类型名可省略struct.
7.5 结构体变量的初值化与数组相似,数据表中的数据被依次赋给成员,未赋值的成员取同类型的数据0.如果成员自身是结构体或数组,数据表中的相应数据可以是内嵌数据表.
7。
6 结构体变量的整体使用有以下四种:
⑴赋值:结构体变量=同类型结构体变量
⑵求存储量:sizeof 结构体变量
⑶取地址:&结构体变量
⑷初始化
7.7 结构体成员名的使用格式有两种:
格式一结构体变量。
成员名
格式二结构体指针—〉成员名
其中,。
和—〉统称成员运算,均是左结合.
结构体成员可作为普通变量使用。
7。
8 结构体成员的调用格式中有成员运算,因此,它参与运算(或操作)时,要适当加括号。
7。
9 结构体成员可与普通变量、其它结构体的成员同名,也可与其上、下层结构体的成员同名。
7。
10 元素为结构体的数组称作结构体数组,以结构体为基类型的指针称作结构体指针,它们的定义和使用与普通数组和普通指针基本相同.
7。
11 共用体与结构体相似,主要区别有:①定义共用体的保留字为union;②同一共用体数据中各成员的基址相同,整体存储量为其成员的存储量之最大者。
③共用体中最后一次赋值的成员将覆盖之前赋值的所有成员,因此,只有最后一次赋值的成员有意义.④共用体变量初始化时,数据表中只有一个数据或数据表,它被赋给第一个成员。
7。
12 定义枚举类型的一般语句格式和功能: 格式 enum 标识符{枚举元素表}变量表;
功能指定枚举类型名,指定枚举元素的值,定义枚举型变量。
第一个枚举元素的默认值为0,其它枚举元素的默认值为其前者加1。
上述“标识符”和枚举“变量表”可缺省。
7。
13 枚举元素属只读变量,其值不可修改。
7。
14 枚举型数据与int型兼容,存储量相同,但是,把int数据赋给枚举变量需强制转换类型。
7。
15 typedef语句的一般格式和功能为:格式 typedef 数据类型名别名表;
功能给指定数据类型增加一组别名。
7。
16 定义指针类型别名的格式为:
格式 typedef 类型名*别名,…,*别名;
7。
17 定义数据类型别名的格式为:
格式 typedef 元素类型名
别名[第1维大小]…[第n维大小],…;
7。
18 typedef语句可在定义结构体、共同体、枚举类型的同时给它增加一组别名。
第8章类和对象
8.1 面向对象程序设计方法可简单地定义为:以类为核心、以对象为基本操作单元、以消息传递为基本操作、具有继承机制的程序设计方法。
8。
2 面向对象中的对象是对具体客观事物的抽象,包括属性抽象和行为抽象两个方面。
8。
3 属性是对象的静态特征,被抽象为成员变量,又称数据、数据结构等。
8。
4 行为是对象的动态特征,被抽象为成员函数,又称操作、运算、功能、方法、算法等。
8.5 属性和行为是对象的两个要素,对象是由其属性和行为组成的有机体。
把对象的数据(属性)和操作代码(行为)封装成相对独立的基本单位称作封装或封装性.即,对象=数据结构+算法.
8.6 类是具有相同属性和行为的一组对象的模板,是一组对象的共性之抽象。
8。
7 定义类的一般语句格式和功能为: 格式 class 类名{访问权限:成员变量和成员函数……}对象表;
功能指定类名,指定类中成员及其访问权限. 8.8 类的成员访问权限分为三种:
private: 私有的-—不对外(不可见)。
public: 公有的-—对外(可见)。
protected: 保护的—-仅对子类(可见)。
8。
9 成员的默认访问权限是private,新规定的访问权限取代之前的访问权限.
8。
10 定义类的关键字class可改用struct,后者规定,成员的默认访问权限是public。
8.11 定义对象的一般语句格式和功能为:
格式类名对象名(实参表或对象)
功能创建指定对象,并初始化。
注意:省略全部实参时,要连同()一起省略。
8.12 由类创建对象称作类的实例化,对象又称类的实例.同类对象具有相同数据结构和操作。
8.13 类的成员可在类体外定义,但必须在类体中作相应声明,定义时必须在函数名前声明所在的类“类名::”,此“::"称作作用域限定符.
8。
14 类的成员函数只占一份存储空间,同类对象其享成员函数,对象只存储其成员变量。
8。
15 访问对象中成员的一般格式为:
格式对象名。
公有成员变量名
格式对象名。
公有成员函数名(实参表)
格式对象指针—〉公有成员变量名
格式对象指针-〉公有成员函数名(实参表) 8。
16 在定义类时,其成员没有访问权限,均可访问.
8.17 在定义类时,当前对象的指针为this,未被形参屏蔽的成员可省略前缀.
8.18 对象与外界交流信息又称传递消息,形式上表现为调用成员函数.
8。
19 对象中的公用成员又称对外接口,只要接口不变,对类的内部修改不影响类外程序。
8。
20 在定义类时,通常,把所有数据和不提供给外界使用的操作指定为私有的,使它们在外界只能被公有的操作访问。
这种做法称作信息隐蔽或隐蔽性.
第9章关于类和对象的进一步讨论
9。
1 构造函数是一个特殊成员函数.从形式上说,构造函数与类同名。
从机制上说,构造函数在创建对象时被自动调用,通常用于初始化对象。
9.2 每个类都有其构造函数。
无形参且函数体为空的构造函数可省略,此时称作隐式构造函数。
9.3 类中的成员变量不占内存,在定义类时,不允许给成员变量赋初值。
9.4 对象的初始化有以下几种格式:
格式一类名对象名={数据表}
功能把数据表中数据依次赋给对象的成员变量。
注意:此格式要求,成员变量均是公有的。
格式二类名对象名=对象。