1. 数据封装就是将一组数据和与这组数据相关的操作组装在一起,形成一个实体,这个实体就是( )。 A.类 B.对象 C.函数体 D.数据块 答题: A. B. C. D. (已提交) -->参考答案:A 问题解析: |
2. 类的实例化是指( )。 A.定义类 B.创建类的对象 C.指明具体类 D.调用类的成员 答题: A. B. C. D. (已提交) -->参考答案:B 问题解析: |
3. 下列说法正确的是( )。 A.类定义中只能说明函数成员的函数头,不能定义函数体 B.类中的函数成员在类体之外定义时必须要与类声明在同一文件中 C.类中的函数成员可以在类体中定义,也可以在类体之外定义 D.在类体之外定义的函数成员不能操作该类的私有数据成员 答题: A. B. C. D. (已提交) -->参考答案:C 问题解析: |
4. 类的构造函数被自动调用执行的情况是在创建该类的( )时。 A.成员函数 B.数据成员 C.对象 D.友元函数 答题: A. B. C. D. (已提交) -->参考答案:C 问题解析: |
5. 析构函数的特征是( )。 A.一个类中只能定义一个析构函数 B.析构函数名与类名不同 C.析构函数的定义只能在类体中 D.析构函数可以有一个或多个参数 答题: A. B. C. D. (已提交) -->参考答案:A 问题解析: |
6. 关于成员函数特征的下列描述中,错误的是( )。 A.成员函数一定是内联函数 B.成员函数可以重载 C.成员函数可以设置参数的默认值 D.成员函数可以是静态的 答题: A. B. C. D. (已提交) -->参考答案:A 问题解析: |
7. 已知类A是类B的友元,类B是类C的友元,则( )。 A.类A一定是类C的友元 B.类C一定是类A的友元 C.类C的成员函数可以访问类B的对象的任何成员 D.类A的成员函数可以访问类B的对象的任何成员 答题: A. B. C. D. (已提交) -->参考答案:D 问题解析: |
8. 在类定义的外部,可以被访问的成员有( )。 A.所有类成员 B.private或protected的类成员 C.public的类成员 D.private或public的类成员 答题: A. B. C. D. (已提交) -->参考答案:C 问题解析: |
思考题
1.结构和类有什么区别?如果把程序中定义结构的关键字struct直接改成class,会有什么问题?用教材上的一个例程试一试,想一想做什么修改能使程序正确运行?
【解答】
结构是数据的封装,类是数据和操作的封装。可以把结构看成是类的特例。结构和类都可以用关键字struct或class定义。区别是,struct定义的结构或类的全部成员都是公有的,用class定义的结构或类不做声明的成员是私有的。
若把struct改成class,只需要把全部成员定义为public就可以了。
2.有说明
class A
{ int a;
double x;
public:
funMember();
};
A a1, a2, a3 ;
编译器为对象a1、a2和a3开辟了什么内存空间?它们有各自的funMember函数的副本吗?C++通过什么机制调用类的成员函数?
【解答】
开辟的存储空间有a1.a, a1.x, a2.a, a2.x, a3.a, a3.x。各对象没有funMember函数的副本,C++通过this指针调用成员函数。
3.C++提供了默认版本的构造函数,为什么还需要用户自定义构造函数?编写一个验证程序,说明自定义构造函数的必要性。
【解答】
类的默认构造函数可以建立基本类型数据成员的存储空间。基于以下两个原因,需要用户定义构造函数:
(1)对数据成员的值做指定初始化;
(2)类的数据是由指针管理的堆。
程序略。
4.试从定义方式、访问方式、存储性质和作用域分析类的一般数据成员和静态数据成员的区别,并编写一个简单程序验证它。
【解答】
定义方式 | 访问方式 | 存储性质 | 作用域 | |
---|---|---|---|---|
一般数据成员 | 类中定义 | 对象.数据成员 | 局部数据 | 由访问属性public, protected, private决定 |
静态数据成员 | 类中声明,类外定义 | 对象.数据成员 类::数据成员 | 全局数据 |
程序略。
5.试从定义方式、调用方式分析常成员函数、静态成员函数和友员函数的区别。考察教材的例6-15,若class Goods的指针域
Goods * next;
被声明为私有(private)成员,程序会出现什么错误?做什么最小修改能使程序正确运行?请你试一试。
【解答】
定义方式 | 调用方式 | |
---|---|---|
常成员函数 | 函数原型以const做后缀 this指针被约束为指向常量的常指针 | 与一般成员函数调用形式相同 对数据成员只读 |
静态成员函数 | 以static做函数原型前缀 没有this指针 | 通过类或对象调用 用于操作静态数据成员 |
友员函数 | 以friend做函数原型前缀 没有this指针 | 通过参数访问对象 可以访问对象的不同属性的成员 |
在例6-15中,若把next声明为私有数据成员,只须把有关指针操作的函数定义为友员函数就可以了:
friend void purchase( Goods * &f, Goods *& r, int w );
friend void sale( Goods * & f , Goods * & r );
6.设有
class M { int a ;};
class N { M m; int b; void fun(){ /*……*/ } };
int main() { N n; N *p=&n; /*……*/ }
描述在N::fun中如何访问M类的数据成员a;在main函数中又如何访问对象n的全部数据成员?
【解答】
在N::fun中访问M类的数据成员a的形式是: m.a
在main函数中访问M类的数据成员的形式是: n.b,n.m.a
程序设计
1.定义一个Book(图书)类,在该类定义中包括
数据成员:bookname(书名)、price(价格)和number(存书数量);
成员函数:display()显示图书的情况;borrow()将存书数量减1,并显示当前存书数量;restore()将存书数量加1,并显示当前存书数量。
在main函数中,要求创建某一种图书对象,并对该图书进行简单的显示、借阅和归还管理。
【解答】
#include <iostream>
using namespace std;
class Book
{ public:
voidsetBook(char*,double,int);
void borrow();
void restore();
void display();
private:
charbookname[40];
double price;
int number;
};
//在类外定义Book类的成员函数
void Book::setBook(char *name, double pri, intnum)
{ strcpy(bookname, name);
price=pri;
number=num;
}
void Book::borrow()
{ if (number==0 )
{ cout<< "已没存书,退出!" <<endl;
abort();
}
number = number - 1;
cout<< "借一次,现存书量为:" << number <<endl;
}
void Book::restore()
{ number = number + 1;
cout<< "还一次,现存书量为:" << number <<endl;
}
void Book::display()
{ cout<< "存书情况:" <<endl
<< "bookname:" <<bookname<<endl
<< "price:" << price <<endl
<< "number:" << number <<endl;
}
int main()
{ char flag, ch;
Book computer;
computer.setBook( "c++程序设计基础" , 32, 1000 );
computer.display();
ch = 'y';
while ( ch == 'y' )
{ cout<< "请输入借阅或归还标志(b/r):";
cin>> flag;
switch ( flag )
{ case 'b': computer.borrow(); break;
case 'r': computer.restore();
}
cout<< "是否继续?(y/n)";
cin>>ch;
}
computer.display();
}
2.定义一个Box(盒子)类,在该类定义中包括
数据成员:length(长)、width(宽)和height(高);
成员函数:构造函数Box,设置盒子长、宽和高三个初始数据;用函数volume计算并输出盒子的体积。
在main函数中,要求创建Box对象,并求盒子的体积。
【解答】
#include <iostream>
using namespace std;
class BOX
{ public:
BOX(double l,double w,double h)
{ length=l;
width=w;
height=h;
}
void volume()
{ cout<<"volume="<<length*width*height<<endl;
}
private:
double length,width,height;
};
int main()
{ BOX box1(1,3,5);
box1.volume();
BOX box2(2,4,6);
box2.volume();
}
3.定义一个Student类,在该类定义中包括:一个数据成员score(分数)及两个静态数据成员total(总分)和学生人数count;成员函数scoretotalcount(double s) 用于设置分数、求总分和累计学生人数;静态成员函数sum()用于返回总分;静态成员函数average()用于求平均值。
在main函数中,输入某班同学的成绩,并调用上述函数求全班学生的总分和平均分。
【解答】
#include <iostream>
using namespace std;
class student
{ public:
voidscoretotalcount( double s )
{ score = s;
total = total + score;
count++;
}
static double sum()
{ return total;
}
static double average()
{ return total / count;
}
private:
double score;
static double total;
static double count;
};
double student::total=0;
double student::count=0;
int main()
{ inti,n; double s;
cout<< "请输入学生人数:";
cin>> n;
student stu;
for(i=1; i<=n; i++ )
{ cout<< "请输入第" <<i<< "个学生的分数:";
cin>> s;
stu.scoretotalcount( s );
}
cout<< "总分:" << student::sum() <<endl;
cout<< "平均分:" << student::average() <<endl;
}
4.定义一个表示点的结构类型Point和一个由直线方程y = ax + b确定的直线类Line。结构类型Point有x和y两个成员,分别表示点的横坐标和纵坐标。Line类有两个数据成员a和b,分别表示直线方程中的系数。Line类有一个成员函数print用于显示直线方程;友员函数setPoint(Line &l1,Line &l2)用于求两条直线的交点。在main函数中,建立两个直线对象,分别调用print函数显示两条直线的方程,并调用函数setPoint求这两条直线的交点。
【解答】
#include <iostream>
using namespace std;
struct point
{ double x; double y; };
class line
{ public:
line(double u,double v)
{ a=u; b=v; }
void print()
{ cout<<"y="<<a<<"x+"<<b<<endl; }
friend point setpoint(line &l1,line &l2);
private:
double a,b;
};
pointsetpoint(line &l1,line &l2)
{ point p;
p.x=(l2.b-l1.b)/(l1.a-l2.a);
p.y=(l1.a*l2.b-l2.a*l1.b)/(l1.a-l2.a);
return p;
}
int main()
{ pointsetp;
line l1(2,3),l2(4,5);
cout<<"直线l1: ";
l1.print();
cout<<"直线l2: ";
l2.print();
setp=setpoint(l1,l2);
cout<<"直线l1和直线l2的交点:("<<setp.x<<","<<setp.y<<")"<<endl;
}
|