收藏 分销(赏)

C++第四版习题解答-下.docx

上传人:二*** 文档编号:4457363 上传时间:2024-09-23 格式:DOCX 页数:62 大小:80KB 下载积分:5 金币
下载 相关 举报
C++第四版习题解答-下.docx_第1页
第1页 / 共62页
本文档共62页,全文阅读请下载到手机保存,查看更方便
资源描述
《C++程序设计根底》〔第4版〕〔下〕 习题与解答 第6章 类与对象 6.1 选择题 1.假设有以下说明,那么在类外使用对象objX成员的正确语句是〔 C 〕。 class X { int a; void fun1(); public: void fun2(); }; X objX; 〔A〕objX.a=0;〔B〕objX.fun1();〔C〕objX.fun2();〔D〕X::fun1(); 2.假设有以下说明,那么对n的正确访问语句是〔 B 〕。 class Y { //… ; public: static int n; }; int Y::n; Y objY; 〔A〕n=1;〔B〕Y::n=1;〔C〕objY::n=1;〔D〕Y->n 3.假设有以下类Z说明,那么函数fStatic中访问数据a错误的选项是〔 C 〕。 class Z { static int a; public: static void fStatic(Z&); }; int Z::a=0; Z objZ; 〔A〕void Z::fStatic() { objZ.a =1; } 〔B〕void Z::fStatic() { a = 1; } 〔C〕void Z::fStatic() { this->a = 0; } 〔D〕void Z::fStatic() { Z::a = 0; } 4.假设有以下类W说明,那么函数fConst的正确定义是〔 A 〕。 class W { int a; public: void fConst(int&) const; }; 〔A〕void W::fConst( int &k )const { k = a; } 〔B〕void W::fConst( int &k )const { k = a++; } 〔C〕void W::fConst( int &k )const { cin >> a; } 〔D〕void W::fConst( int &k )const { a = k; } 5.假设有以下类T说明,那么函数fFriend的错误定义是〔 C 〕。 class T { int i; friend void fFriend( T&, int ); }; 〔A〕void fFriend( T &objT, int k ) { objT.i = k; } 〔B〕void fFriend( T &objT, int k ) { k = objT.i; } 〔C〕void T::fFriend( T &objT, int k ) { k += objT.i; } 〔D〕void fFriend( T &objT, int k ) { objT.i += k; } 6.在类定义的外部,可以被访问的成员有〔 C 〕。 〔A〕所有类成员〔B〕private或protected的类成员 〔C〕public的类成员〔D〕public或private的类成员 7.关于this指针的说确的是〔 C 〕。 〔A〕this指针必须显式说明〔B〕定义一个类后,this指针就指向该类 〔C〕成员函数拥有this指针〔D〕静态成员函数拥有this指针 8.说明一个类的对象时,系统自动调用〔 B 〕;撤销对象时,系统自动调用〔 C 〕。 〔A〕成员函数〔B〕构造函数〔C〕析构函数〔D〕友元函数 9.下面对构造函数的不正确描述是〔 C 〕。 〔A〕用户定义的构造函数不是必须的〔B〕构造函数可以重载 〔C〕构造函数可以有参数,也可以有返回值〔D〕构造函数可以设置默认参数 10.下面对析构函数的正确描述是〔 C 〕。 〔A〕系统在任何情况下都能正确析构对象〔B〕用户必须定义类的析构函数 〔C〕析构函数没有参数,也没有返回值〔D〕析构函数可以设置默认参数 11.关于类的静态成员的不正确描述是〔 D 〕。 〔A〕静态成员不属于对象,是类的共享成员 〔B〕静态数据成员要在类外定义和初始化 〔C〕静态成员函数不拥有this指针,需要通过类参数访问对象成员 〔D〕只有静态成员函数可以操作静态数据成员 12.在以下选项中,〔 C 〕不是类的成员函数。 〔A〕构造函数〔B〕析构函数〔C〕友元函数〔D〕复制构造函数 13.下面对友元的错误描述是〔 D 〕。 〔A〕关键字friend用于声明友元 〔B〕一个类中的成员函数可以是另一个类的友元 〔C〕友元函数访问对象的成员不受访问特性影响 〔D〕友元函数通过this指针访问对象成员 14.假设class B中定义了一个class A的类成员A a,那么关于类成员的正确描述是〔 C 〕。 〔A〕在类B的成员函数中可以访问A类的私有数据成员 〔B〕在类B的成员函数中可以访问A类的保护数据成员 〔C〕类B的构造函数可以调用类A的构造函数做数据成员初始化 〔D〕类A的构造函数可以调用类B的构造函数做数据成员初始化 6.2 阅读以下程序,写出运行结果 1. #include<iostream> using namespace std; class A { public : int f1(); int f2(); void setx( int m ) { x = m; cout << x << endl; } void sety( int n ) { y = n; cout << y << endl; } int getx() { return x; } int gety() { return y; } private : int x, y; }; int A::f1() { return x + y; } int A::f2() { return x - y; } int main() { A a; a.setx( 10 ); a.sety( 5 ); cout << a.getx() << '\t' << a.gety() << endl; cout << a.f1() << '\t' << a.f2() << endl; } 【解答】 10 5 10 5 15 5 2. #include<iostream> using namespace std; class T { public : T( int x, int y ) { a = x; b = y; cout << "调用构造函数1." << endl; cout << a << '\t' << b << endl; } T( T &d ) { cout << "调用构造函数2." << endl; cout << d.a << '\t' << d.b << endl; } ~T() { cout << "调用析构函数."<<endl; } int add( int x, int y = 10 ) { return x + y; } private : int a, b; }; int main() { T d1( 4, 8 ); T d2( d1 ); cout << d2.add( 10 ) << endl; } 【解答】 调用构造函数1. 4 8 调用构造函数2. 4 8 20 调用析构函数. 调用析构函数. 3. #include<iostream> using namespace std; class T { public: T(int x) { a=x; b+=x; }; static void display(T c) { cout<<"a="<<c.a<<'\t'<<"b="<<c.b<<endl; } private: int a; static int b; }; int T::b=5; int main() { T A(3), B(5); T::display(A); T::display(B); } 【解答】 a=3 b=13 a=5 b=13 4. #include<iostream> using namespace std; #include<cmath> class Point { public : Point( float x, float y ) { a = x; b = y; cout<<"点( "<<a<<", "<<b<<" )"; } friend double d( Point &A, Point &B ) { return sqrt((A.a-B.a)*(A.a-B.a)+(A.b-B.b)*(A.b-B.b)); } private: double a, b; }; int main() { Point p1( 2, 3 ); cout << " 到"; Point p2( 4, 5 ); cout << "的距离是:" << d( p1,p2 ) << endl; } 【解答】 点〔3,4〕到点〔4,5〕的距离是:2.82843 5. #include<iostream> using namespace std; class A { public : A() { a = 5; } void printa() { cout << "A:a = " << a << endl; } private : int a; friend class B; }; class B { public: void display1( A t ) { t.a ++; cout << "display1:a = " << t.a << endl; }; void display2( A t ) { t.a --; cout << "display2:a = " << t.a << endl; }; }; int main() { A obj1; B obj2; obj1.printa(); obj2.display1( obj1 ); obj2.display2( obj1 ); obj1.printa(); } 【解答】 A:a = 5 display1:a = 6 display2:a = 4 A:a = 5 6. #include<iostream> using namespace std; class A { public: A(int x):a(x=0){ } void getA(int &A) { A=a; } void printA() { cout<<"a="<<a<<endl; } private: int a; }; class B { public: B(int x, int y):aa(x=0) { b = y; } void getAB(int &A, int &outB) { aa.getA(A); outB=b; } void printAB() { aa.printA(); cout<<"b="<<b<<endl; } private: A aa; int b; }; int main() { A objA; int m=5; objA.getA(m); cout<<"objA.a="<<m<<endl; cout<<"objB:\n"; B objB; objB.getAB(12,56); objB.printAB(); } 【解答】 objA:a=5 objB: a=12 b=56 6.3 思考题 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.试从定义方式、访问方式、存储性质和作用域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 { public: int a; }; class N { public: 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 6.4 编程题 1.定义一个Book〔图书〕类,在该类定义中包括以下数据成员和成员函数。 数据成员: bookname〔书名〕、price〔价格〕和number〔存书数量〕。 成员函数: display()显示图书的情况;borrow()将存书数量减1,并显示当前存书数量;restore()将存书数量加1,并显示当前存书数量。 在main函数中,要求创建某一种图书对象,并对该图书进展简单的显示、借阅和归还管理。 【解答】 #include <iostream> using namespace std; class Book { public: void setBook(char*,double,int); void borrow(); void restore(); void display(); private: char bookname[40]; double price; int number; }; //在类外定义Book类的成员函数 void Book::setBook(char *name, double pri, int num) { 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,设置盒子的长、宽和高3个初始数据;成员函数setBox对数据成员置值;成员函数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: void scoretotalcount( 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() { int i,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; }; point setpoint( 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() { point setp; 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; } 5.用类成员结构修改习题6.4第4小题的程序,使其实现一样的功能。定义Point类和Line类,表示点和线;定义setPoint类,包含两个Line类成员和一个表示直线交点的Point成员,并定义类中求直线交点的成员函数。编写每个类相应的成员函数和测试用的主函数。 【解答】 略。 第7章 运算符重载 7.1 选择题 1.在以下运算符中,不能重载的是〔 B 〕。 〔A〕 !〔B〕sizeof〔C〕new〔D〕delete 2.在以下关于运算符重载的描述中,〔 D 〕是正确的。 〔A〕可以改变参与运算的操作数个数〔B〕可以改变运算符原来的优先级 〔C〕可以改变运算符原来的结合性 〔D〕不能改变原运算符的语义 3.在以下函数中,不能重载运算符的函数是〔 B 〕。 〔A〕成员函数 〔B〕构造函数〔C〕普通函数 〔D〕友元函数 4.要求用成员函数重载的运算符是〔 A 〕。 〔A〕=〔B〕==〔C〕<=〔D〕++ 5.要求用友元函数重载的ostream类输出运算符是〔C 〕。 〔A〕=〔B〕[]〔C〕<<〔D〕() 6.在以下关于类型转换的描述中,错误的选项是〔 A 〕。 〔A〕任何形式的构造函数都可以实现数据类型转换。 〔B〕带非默认参数的构造函数可以把根本类型数据转换成类类型对象。 〔C〕类型转换函数可以把类类型对象转换为其他指定类型对象。 〔D〕类型转换函数只能定义为一个类的成员函数,不能定义为类的友元函数。 7.2 阅读以下程序,写出运行结果 1. #include <iostream> using namespace std; class T { public : T() { a = 0; b = 0; c = 0; } T( int i, int j, int k ) { a = i; b =j; c = k; } void get( int &i, int &j, int &k ) { i = a; j = b; k = c; } T operator* ( T obj ); private: int a, b, c; }; T T::operator* ( T obj ) { T tempobj; tempobj.a = a * obj.a; tempobj.b = b * obj.b; tempobj.c = c * obj.c; return tempobj; } int main() { T obj1( 1,2,3 ), obj2( 5,5,5 ), obj3; int a, b, c; obj3 = obj1 * obj2; obj3.get( a, b, c ); cout<<"( obj1*obj2 ): " <<"a = "<<a<<'\t'<<"b = "<<b<<'\t'<<"c = "<<c<<'\n'; (obj2*obj3).get( a, b, c ); cout<<"( obj2*obj3 ): " <<"a = "<<a<<'\t'<<"b = "<<b<<'\t'<<"c = "<<c<<'\n'; } 【解答】 ( obj1 * obj2 ): a = 5 b = 10 c = 15 ( obj2 * obj3 ): a = 25 b = 50 c = 75 2. #include <iostream> using namespace std; class Vector { public: Vector(){ } Vector(int i,int j) { x = i; y = j; } friend Vector operator+ ( Vector v1, Vector v2 ) { Vector tempVector; tempVector.x = v1.x + v2.x; tempVector.y = v1.y + v2.y; return tempVector; } void display() { cout << "( " << x << ", " << y << ") "<< endl; } private: int x, y; }; int main() { Vector v1( 1, 2 ), v2( 3, 4 ), v3; cout << "v1 = "; v1.display(); cout << "v2 = "; v2.display(); v3 = v1 + v2; cout << "v3 = v1 + v2 = "; v3.display(); } 【解答】 v1 = ( 1, 2 ) v2 = ( 3, 4 ) v3 = v1 + v2 = ( 4, 6 ) 7.3 思考题 1.一个运算符重载函数被定义为成员函数或友元函数后,在定义方式、解释方式和调用方式上有何区别?可能会出现什么问题?请用一个实例说明之。 【解答】 以二元运算符为例。 运算符重载 定义 解释 调用 成员函数 Obj& operator op(); Obj operator op(object); Obj.operator op() ObjL.operator op(ObjR) Obj op 或 op Obj ObjL op ObjR 左操作数通过this指针指定,右操作数由参数传递 友员函数 friend Obj & operator op(Obj &); friend Obj operator op(Obj,Obj); operator op(Obj) operator op(ObjL,ObjR) Obj op 或 op Obj ObjL op ObjR 操作数均由参数传递 可能会出现的问题: 〔1〕运算符的左右操作数不同,须用友员函数重载; 〔2〕当运算符的操作需要修改类对象状态时,应用成员函数重载。 〔3〕友员函数不能重载运算符 = () [] -> 必须要用友员函数重载的运算符 >> << 程序略。 2.类类型对象之间、类类型和根本类型对象之间用什么函数进展类型转换?归纳进展类型转换的构造函数和类型转换函数的定义形式、调用形式和调用时机。 【解答】 构造函数可以把根本类型、类类型数据转换成类类型数据;类类型转换函数可以在类类型和根本数据类型之间做数据转换。 定义形式 调用形式 调用时机 构造函数 ClassX::ClassX(arg,arg1=E1,...,argn=En); 隐式调用 建立对象、参数传递时 类类型转换函数 ClassX::operator Type(); 用类型符显式调用; 自动类型转换时隐式调用 需要做数据类型转换时 7.4 编程题 1.分别使用成员函数和友元函数编写程序重载运算符“+〞,使该运算符能实现两个字符串的连接。 【解答】 〔1〕 使用成员函数 #include <iostream> #include<cstring> using namespace std; class s { public: s(){ *str = '\0'; } s( char *pstr ) { strcpy( str,pstr ); char *gets() { return str; } s operator+( s obj ); private: char str[10]; }; s s::operator+( s obj ) { strcat( str,obj.str ); return str; //或return *this } int main() { s obj1( "Visual" ),obj2( " C++" ),obj3; obj3 = obj1 + obj2; cout << obj3.gets() << endl; } 〔2〕使用友员函数 #include <iostream> #include<cstring> using namespace std; class s { public: s(){ *str= '\0'; } s( char *pstr ) { strcpy( str,pstr ); } char *gets() { return str; } friend s operator+( s obj1,s obj2 ); private: char str[100]; }; s operator+( s obj1,s obj2 ) { s tempobj; strcat( tempobj.str,obj1.str ); strcat( tempobj.str,obj2.str ); return tempobj; } int main() { s obj1( "Visual" ),obj2( " C++" ),obj3; obj3 = obj1 + obj2; cout << obj3.gets() << endl; } 2.定义一个整数计算类Integer,实现短整数 +、-、*、/ 根本算术运算。要求:可以进展数据围检查〔-32 768~32 767,或自行设定〕,数据溢出时显示错误信息并中断程序运行。 【解答】 #include <iostream> using namespace std; class Integer { private: short a; public: Integer (short n=0){ a=n;} Integer operator +(Integer); Integer operator -(
展开阅读全文

开通  VIP会员、SVIP会员  优惠大
下载10份以上建议开通VIP会员
下载20份以上建议开通SVIP会员


开通VIP      成为共赢上传

当前位置:首页 > 考试专区 > 其他

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2025 宁波自信网络信息技术有限公司  版权所有

客服电话:4009-655-100  投诉/维权电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服