C++友元习题
- 格式:doc
- 大小:42.50 KB
- 文档页数:11
C++友元函数与友元类选择题1.以下哪项正确描述了友元函数的作用?o A. 它可以访问类的所有私有成员和保护成员。
o B. 它只能访问类的公有成员。
o C. 它是用来替代类的成员函数。
o D. 它提高了类的封装性。
答案: A解析: 友元函数被声明在类中以访问类的私有和保护成员,但不属于类的成员函数,因此不提高封装性。
2.友元函数的声明应出现在类的哪一部分?o A. public部分o B. protected部分o C. private部分o D. 不需要出现在特定部分答案: A解析: 友元函数可以声明在类的public、protected或private部分,但通常为了控制访问权限而放在private部分。
3.以下代码中,display函数是否是A类的友元函数?o B. 不是o C. 只有当display函数被声明在A类中时才是。
o D. 友元函数必须与类定义在同一个文件中。
答案: B解析: display函数没有被声明为A类的友元,因此它不能访问A类的私有成员。
4.如何正确声明友元类?o A. 在类的定义中使用friend关键字。
o B. 使用class关键字在类定义内部声明。
o C. 在类的外部使用friend关键字。
o D. 友元类不需要特殊声明。
答案: A解析: 友元类应在需要被访问的类中使用friend关键字声明。
5.一个友元类的所有成员函数可以访问另一个类的哪些成员?o A. 所有成员,包括私有和保护。
o B. 只能访问公有成员。
o C. 只有在friend声明中指定的成员。
o D. 友元类不能访问另一个类的成员。
答案: A解析: 友元类的所有成员函数可以访问另一个类的所有成员,包括私有和保护成员。
6.在类B中声明A类为友元,以下哪项是正确的?o B. friend class A;o C. friend A B;o D. friend B A;答案: B解析: 正确的声明应为friend class A;在B类的定义中。
C++中友元的实例详解C++中友元的实例详解尽管友元被授予从外部访问类的私有部分的权限,但他们并不与⾯向对象的编程思想相悖;相反他提⾼了公共接⼝的灵活性。
⼀、友元类友元声明可以位于公有、私有活保护部分、其所在位置⽆关紧要我直接贴出⼀个摘⾃< c++ primer plus >的例⼦来演⽰ c++ 友元类其中 Remote 为 Tv的友元类。
Tv.h#ifndef TV_H_#define TV_H_/*⼀个类电视 */class Tv{public:friend class Remote; //Remote类可以访问Tv Privite 的私有部分enum {off,on //开关};enum{MinVal,MaxVal=20 //⾳量};enum {Antena,Cable //使⽤的天线、还是电缆};enum{TV ,DVD //⼯作模式};Tv(int s = off, int mc = 125) :state(s), volume(5), maxchannel(mc),channel(5), mode(Cable), input(TV) {}void onoff() { state = (state == on) ? off : on; }bool ison()const { return state == on; }bool volup(); //增⼤声⾳bool voldown(); //减⼩声⾳void chanup(); //频道 +void chandown();//频道 -void set_mode() { mode = (mode == Antena) ? Cable : Antena; }void set_input() { input = (input == TV) ? DVD : TV; }void settings()const; //显⽰所有设置private:int state; // 开或者关int volume; // ⾳量int maxchannel; //最⼤int channel; //当前频道int mode; // ⼴播还是电缆int input; //Tv 或者 DVD};/*Remote 的定义(遥控器) */class Remote {private :int mode; // 控制 TV 或 DVDpublic:Remote(int m = Tv::TV) :mode(m) {}bool volup(Tv & t) { return t.volup(); }bool voldown(Tv & t) { return t.voldown(); }void onoff(Tv & t) { return t.onoff(); }void chanup(Tv & t) { return t.chanup(); }void chandown(Tv & t) { return t.chandown(); }void set_chan(Tv &t, int c) { t.channel = c; } //访问了Tv的私有成员void set_mode(Tv &t) { t.set_mode(); }void set_input(Tv &t) { t.set_input(); }};#endif // TV_H_Tv.cpp#include "stdafx.h"#include "Tv.h"#include <iostream>bool Tv::volup() {if (volume < MaxVal) {volume++;return true;}else {return false;}}bool Tv::voldown() {if (volume > MinVal) {volume--;return true;}else {return false;}}void Tv::chanup() {if (channel < maxchannel) channel++;else channel = 1;}void Tv::chandown() {if (channel > 1) channel--;else channel = maxchannel;}void Tv::settings() const {using std::cout;using std::endl;cout << "TV is " << (state == off ? "off" : "on") << endl;if (state == on) {cout << "Volume setting =" << volume << endl;cout << "Channel setting = " << channel << endl;cout << "Mode = " << (mode == Antena ? "antenna" : "cable") << endl; cout << "Input = " << (input == TV ? "TV" : "DVD") << endl;}}测试代码:#include "stdafx.h"#include "tv.h"#include <iostream>int main(){using std::cout;Tv s42;cout << "Initial settings for 42 \" Tv: \n";s42.settings();s42.onoff();s42.chanup();cout << " \n Adjusted settings for 42 \" Tv: \n";s42.chanup();cout << "\n Adjusted settings for 42 \" Tv: \n";s42.settings();Remote grey;grey.set_chan(s42, 10);grey.volup(s42);grey.volup(s42);cout << " \n s42 \" settings after using remote: \n";s42.settings();Tv s58(Tv::on);s58.set_mode();grey.set_chan(s58, 58);cout << " \n s58 \" setting: \n";s58.settings();system("pause");return 0;}运⾏结果:Initial settings for 42 " Tv:TV is offAdjusted settings for 42 " Tv:Adjusted settings for 42 " Tv:TV is onVolume setting =5Channel setting = 7Mode = cableInput = TVs42 " settings after using remote:TV is onVolume setting =7Channel setting = 10Mode = cableInput = TVs58 " setting:TV is onVolume setting =5Channel setting = 58Mode = antennaInput = TV请按任意键继续. . .上述代码中将Remote类设置成为了Tv类的友元类,但事实上我们看到:唯⼀访问Tv的成员的⽅法是void set_chan(Tv &t, int c) { t.channel = c; } ,因此它是唯⼀需要友元的⽅法。
第一章习题一、选择填空1.下列各种高级语言中,()是面向对象的程序设计语言。
A.BASIC;B.PASCAL;C.C++D.Ada2.下列各种高级语言中,()是最早提出了对象的概念。
A.Algol60;B.Simula67;C.Smalltalk;D.C++3.下述面向对象抽象的原理中,()是不对的。
A.数据抽象;B.行为共享;C.进化;D.兼容;4.()不是面向对象系统所包含的要数。
A.重载;B.对象;C.类;D.继承;5.关于C++与C语言的关系的描述中,()是错误的。
A.C语言是C++的一个子集;B.C语言与C++是兼容的;C.C++对C语言进行了一些改进;D.C++和C语言都是面向对象的;6.下面关于对象概念的描述中,()是错误的。
A.对象就是C语言中的结构变量;B.对象代表着正在创建的系统中的一个实体;C.对象是一个状态和操作(或方法)的封装体;D.对象之间的信息传递是通过消息进行的;7.下面关于类概念的描述中,()是错误的。
A.类是抽象数据类型的实现;B.类是具有共同行为的若干对象的统一描述体;C.类是创建对象的样板;D.类就是C语言中的结构类型;8.C++对C语言作了很多改进,下列描述中()使得C语言发生了质变,即从面向过程变成为面向对象。
A.增加了一些新的运算符;B.允许函数重载,并允许设置缺省参数;C.规定函数说明必须用原型;D.引进了类和对象的概念;9.按照标识符的要求,()符号不能组成标识符。
A.连接符;B.下划线;C.大小写字母;D.数字字符;10.下列符号中,()不可作为分隔符。
A.,;B.:;C.?;D.;二、判断下列描述的正确性,对者划√,错者划×。
1.C++引进了引用的概念,对编程带来了很多方便。
Y2.C++允许使用友元,但是友元会破坏封装性。
Y3.C++中使用了新的注释符(//),C语言中注释符(/*…*/)不能在C++中使用。
X4.C++中为了减轻使用者的负担,与C语言相比较C++中减少了一些运算符。
内蒙古科技大学面向对象的程序设计实验报告一、实验目的1.理解静态成员(静态数据成员、静态成员函数)的作用与使用;2.理解友元(友元函数、友元类)的作用于使用。
二、实验环境编译器:Visual C++ 6.0.操作系统:Windows 7旗舰版三、实验内容二、实验内容2.1练习(一):1.理解下面的程序,并在VC++6.0下运行查看结果,回答程序后面的问题。
#include <iostream.h>#include <string.h>class CStudent{public:CStudent(char *n, int a);~CStudent();static void SetAge(int age);private:char *name;int age;static int nTotalObj;};int CStudent::nTotalObj = 0;CStudent::CStudent(char *n, int a):age(a){int nLen = strlen(n);name = new char[nLen+1];strcpy(name,n);name[nLen] = ’\0’;nTotalObj++;}CStudent::~CStudent(){delete[] name;nTotalObj--;}void CStudent::SetAge(int age){this->age = age;}void main(){CStudent stu1("张三",25);CStudent str2("李四",26);cout<<"CStudent::nTotalObj="<<CStudent::nTotalObj<<endl;}问题一:以上程序编译能通过吗,为什么?问题二:成员变量nTotalObj在程序中起什么作用,它是如何实现的?问题三:如果规定该程序的主函数和类CStudent中的成员变量的属性不允许改变,应该如何改正该程序?2.理解下面的程序,并在VC++6.0下运行查看结果,回答程序后面的问题。
第八单元结构体和共用体一、选择题1、说明一个结构体变量时系统分配给它的内存是。
A. 各成员所需要内存量的总和B. 结构体中第一个成员所需内存量C. 成员中占内存量最大者所需的容量D. 结构中最后一个成员所需内存量2、 C 语言结构体类型变量在程序执行期间。
A. 所有成员一直驻留在内存中B. 只有一个成员驻留在内存中C. 部分成员驻留在在内存中D. 没有成员驻留在内存中3、设有以下说明语句struct stu { int a ; float b ; } stutype ;则下面的叙述不正确的是。
A. struct 是结构体类型的关键字B. struct stu 是用户定义的结构体类型C. stutype 是用户定义的结构体类型名D. a 和b 都是结构体成员名4、程序中有下面的说明和定义struct abc { int x;char y;}struct abc s1,s2;则会发生的情况是。
A. 编译出错B. 程序将顺利编译、连接、执行C. 能顺利通过编译、连接、但不能执行D. 能顺利通过编译、但连接出错5、有如下定义struct person { char name[9]; int age;};struct person class[10]={ " Johu", 17,"Paul", 19,"Mary", 18,"Adam",16};根据上述定义,能输出字母M 的语句是。
A. prinft(" %c\n",class[3].name);B. printf(" %c\n",class[3].name[1]);C. prinft(" %c\n",class[2].name[1]);D. printf(" %c\n",class[2].name[0]);6、下面程序的输出是。
习题二一、填空题1. 对运算符进行重载时,不能改变结合性,不能改变操作数个数,不能改变优先级。
2. 当++被重载为后置成员函数时需要0 个参数。
3. 当++被重载为前置成员函数时需要 1 个参数。
4. 在C++中,运算符重载函数可以是成员函数,也可以是友元函数,还可以是普通函数。
5. 友元破坏了类的封装性特性。
6. 类的友元能够访问这个类的所有成员。
7. 类的静态数据成员的初始化是在类外进行的。
8. 类的静态成员函数没有this指针。
9. 类的静态成员函数访问该类的非静态成员可以通过参数传递对象来实现。
10. 不能被重载的类成员函数是构造和析构函数。
二、选择题1. 已知类A有一个带double型参数的构造函数,且将运算符“+”重载为该类友元函数,若如下语句:A x(2.5),y(3.6),z(0); z=x+y; 能够正常运行,运算符重载函数operator+ 应在类中声明为( D )。
A. friend A operator+ (double , double) ;B. friend A operator+ ( double , A &);C. friend A operator+ ( A &, double);D. friend A operator+ ( A & , A &);2. 下列关于运算符重载的描述中,正确的是(D )。
A. 运算符重载可以改变操作数的个数B. 运算符重载可以改变优先级C. 运算符重载可以改变结合性D. 运算符重载不可以改变语法结构3. 友元运算符表达式obj1>obj2被C++编译器解释为(A )。
A. operator>(obj1,obj2)B. >(obj1,obj2)C. obj2.operator>(obj1)D. obj1.operator>(obj2)4. 下列关于C++运算符函数的返回类型的描述中,错误的是(C )。
01.分析以下程序的执行结果#include<iostream.h>class Sample{int n;public:Sample(int i){n=i;}friend int add(Sample &s1,Sample &s2);};int add(Sample &s1,Sample &s2){return s1.n+s2.n;}void main(){Sample s1(10),s2(20);cout<<add(s1,s2)<<endl;}解:本题说明了友元函数的使用方法。
add()是一个友元函数,它返回两个引用对象的n值之和。
所以输出为:30注意:友元函数不是类的成元函数----------------------------------------------------02.分析以下程序的执行结果#include<iostream.h>class B;class A{int i;public:int set(B&);int get(){return i;}A(int x){i=x;}};class B{int i;public:B(int x){i=x;}friend A;int A::set(B &b) // 由于使用了类B的定义,故本函数的定义应放在类B定义之后{return i=b.i;}void main(){A a(1);B b(2);cout<<a.get()<<",";a.set(b);cout<<a.get()<<endl;}解:本题说明友元类的使用方法。
这里将类A设置为类B的友元类,因此,类A的所有成员函数均为类B 的友元函数。
通过调用a.set(b)将b对象的i值赋给a对象的i值。
所以输出为:1,2-------------------------------------------------03.有一个学生类student,包括学生姓名、成绩,设计一个友元函数,比较两个学生成绩的高低,并求出最高分和最低分的学生。
解:#include<iostream.h>#include<string.h>class student{char name[10];int deg;public:student(char na[],int d){strcpy(name,na);deg=d;}char *getname(){ return name;}friend int compare(student &s1,student &s2){if(s1.deg>s2.deg)return 1;else if(s1.deg==s2.deg)return 0;else return -1;};void main(){student st[]={student("王华",78),student("李明",92),student("张伟",62),student("孙强",88)};int i,min=0,max=0;for(i=1;i<4;i++){if(compare(st[max],st[i])==-1)max=i;else if(compare(st[i],st[min])==1)min=i;}cout<<"输出结果:"<<endl;cout<<" 最高分:"<<st[max].getname()<<endl;cout<<" 最低分:"<<st[min].getname()<<endl;}本程序的执行结果如下:输出结果:最高分者:李明最低分者:张伟-------------------------------------------------------------04.有一个学生类student,包括学生姓名、成绩,设计一个友元函数,输出成绩对应的等级:大于等于90:优;80~90:良;70~79:中;60!69:及格;小于60:不及格。
解:#include<iostream.h>#include<string.h>#include<iomanip.h>class student{char name[10];int deg;char level[7];public:student(char na[],int d){strcpy(name,na);deg=d;}char *getname(){ return name;}friend void trans(student &s)if(s.deg>=90)strcpy(s.level,"优");else if(s.deg>=80)strcpy(s.level,"良");else if(s.deg>=70)strcpy(s.level,"中");else if(s.deg>=60)strcpy(s.level,"及格");elsestrcpy(s.level,"不及格");}void disp(){cout<<setw(10)<<name<<setw(6)<<deg<<setw(8)<<level<<endl;}};void main(){student st[]={student("王华",78),student("李明",92),student("张伟",62),student("孙强",88)};cout<<"输出结果:"<<endl;cout<<setw(10)<<"姓名"<<setw(6)<<"成绩"<<setw(8)<<"等级"<<endl;02.05.设计一个类Sample,它有两个私有成员A[]和n(A中元素个数),将对A[]中数据进行各种排序的函数放入到一个友元类process中。
解:process类不包含任何数据成员,包含的公共成员函数如下:getdata(Sample &s); 用于获取对象s的数据insertsort(Sample &s); 用于进行插入排序shellsort(Sample &s); 用于进行希尔排序bubblesort(Sample &s); 用于进行冒泡排序quicksort(Sample &s); 用于进行快速排序selectsort(Sample &s); 用于进行选择排序disp(Sample &s); 用于输出数据本题程序如下:#include<iostream.h>#define Max 100class Sample{int A[Max];int n;friend class process;public:Sample(){n=0;}class process{void qsort(Sample &s,int l,int h);// 私有成员,由quicksort()成员调用public:void getdata(Sample &s);void insertsort(Sample &s);void shellsort(Sample &s);void bubblesort(Sample &s);void quicksort(Sample &s);void selectsort(Sample &s);void disp(Sample &s);};void process::getdata(Sample &s){int i;cout<<"元素个数:";cin>>s.n;for(i=0;i<s;i++){cout<<"输入第"<<i+1<<"个数据:";cin>>s.A[i];}}void process::insertsort(Sample &s) // 插入排序{int i,j,temp;for(i=1;i<s.n;i++){temp=s.A[i];j=i-1;while(temp<s.A[j]){s.A[j+1]=s.A[j];j--;}s.A[j+1]=temp;}}void process::shellsort(Sample &s) // 希尔排序{int i,j,gap,temp;gap=s.n/2;while(gap>0){for(i=gap;i<s;i++){j=i-gap;while(j>=gap)if(s.A[j]>s.A[j+gap]){temp=s.A[j];s.A[j]=s.A[j+gap];s.A[j+gap]=temp;j=j-gap;}else j=0;}gap=gap/2;}}void process::bubblesort(Sample &s) // 冒泡排序{int i,j,temp;for(i=0;i<s.n;i++)for(j=s.n-1;j>=i+1;j--)if(s.A[j]<s.A[j-1]){temp=s.A[j];s.a[j]=s.A[j-1];s.A[j-1]=temp;}}void process::quicksort(Sample &s) // 快速排序{qsort(s,0,s.n-1);}void process::qsort(Sample &s,int l,int h){int i=l,j=h,temp;if(l<h){ temp=s.A[l];do{while(j>i&&s.A[j]>=temp)j--;if(i<j){s.A[i]=s.A[j];i++;}while(i<j&&s.A[i]<=temp)i++;if(i<j){s.A[j]=s.A[i];j--;}}while(i<j);s.A[i]=temp;qsort(s,l,j-1);qsort(s,j+1,h);}}void process::selectsort(Sample &s) // 选择排序{int i,j,k,temp;for(i=0;i<s.n;i++){k=i;for(j=i+1;j<=s.n-1;j++)if(s.A[j]<s.A[k])k=j;temp=s.A[i];s.A[i]=s.A[k];s.A[k]=temp;}}void process::disp(Sample &s){for(int i=0;i<s.n;i++)cout<<s.A[i]<<" ";cout<<endl;}void main(){int sel;Sample s;process p;p.getdata(s);cout<<"原来序列:";p.disp(s);cout<<"0:插入排序1:希尔排序2:冒泡排序3:快速排序4:选择排序其它退出"<<endl;cout<<"选择排序方法:";cin>>sel;switch(sel){case 0:p.insertsort(s);cout<<"插入排序结果:";03.题1.分析以下程序的执行结果#include<iostream.h>class Sample{int n;public:Sample(){}Sample (int m){n=m;}friend void square(Sample &s){s.n=s.n*s.n;}void disp(){cout<<"n="<<n<<endl;}};void main(){Sample a(10);square(a);a.disp();}解:本题应用友元函数修改对象的数据成员。