实验5 友元 常量成员

合集下载

《静态成员与友元》课件

《静态成员与友元》课件
与一般的非静态成员相比,静态成员是类的共享成员,它不依赖于类的实例 而存在,并且在类的所有实例之间是共享的。
静态成员的作用
静态成员可以在类的实例之间共享数据和函数。它们可以用于跟踪类的所有 实例的共同状态,或提供与类相关的全局操作。
静态成员的声明与初始化
静态成员在类的定义中声明,并在类外部进行初始化。它们的生命周期与程序的运行周期相同,直到程序结束。
友元的定义
友元是一种特殊的关系,允许其他类或函数访问另一个类的私有成员。它可以增加程序的灵活性和扩展性。
友元函数与友元类
友元函数是指在类的定义中声明为友元的非成员函数,可以访问该类的私有 成员。友元类是指在类的定义中声明为友元的另一个类。
实例演示
让我们通过一个例子来演示静态成员和友元的用法。我们将创建一个类来管 理学生的信息,并使用静态成员和友元来实现一些特殊操作。
《静态成员与友元》PPT课件
静态成员的定义 静态成员与非静态成员的区别 静态成员演示
静态成员的定义
在C++中,静态成员是类的成员,其属于类本身而不是类的实例。可以通过类 名加作用域运算符(::)来访问静态成员。
静态成员与非静态成员的区别

实验5 静态成员、友元、对象成员

实验5  静态成员、友元、对象成员

实验五静态成员、友元、对象成员1、实验目的:1)掌握静态数据成员的定义及使用;2)掌握静态成员函数的定义及使用。

3)掌握友员函数的定义和使用。

4)理解对象成员的概念5)掌握对象成员的初始化方法2、实验内容:2.1 分析下面的程序,指出程序运行的结果。

1) P132习题3.14,3.15,3.20,3.23,3.24,3.25,3.26代码:3.14#include<iostream.h>class B{public:B(){}B(int i,int j){x=i;y=j;}void printb(){cout<<x<<","<<y<<endl;}private:int x,y;};class A{public:A(){}A(int I ,int j);void printa();private:B c;};A::A(int i,int j):c(i,j){}void A::printa(){c.printb();}int main(){A a(7,8);a.printa();return;}程序运行结果:7,83.15程序代码:#include<iostream.h>class A{public:void set(int i,int j){x=i;y=j;}int get_y(){return y;}private:int x,y;};class box{public:void set(int l,int w,int s,int p){length=l;width=w;label.set(s,p);}int ger_area(){return length*width;}private:int length,width;A label;};int main(){box b;b.set(4,6,1,20);cout<<b.ger_area()<<endl;return 0;}程序运行结果:243.20程序代码:#include<iostream.h>class aclass{public:aclass(){total++;}~aclass(){total--;}int gettotal(){return total;}private:static int total;};int aclass::total=0;int main(){aclass o1,o2,o3;cout<<o1.gettotal()<<"objects in existence\n"; aclass *p;p=new aclass;if(!p){cout<<"Allocation error\n";return 1;}cout<<o1.gettotal();cout<<"objects in existence after allocation\n"; delete p;cout<<o1.gettotal();cout<<"objects in existence after allocation\n"; return 0;}程序运行结果:3 objects in existence4 objects in existence after allocation 3 objects in existence after allocation3.24程序代码:#include<iostream.h>class N{private:int A;static int B;public:N(int a){A=a;B+=a;}static void f1(N m);};void N::f1(N m){cout<<"A="<<m.A<<endl;cout<<"B="<<B<<endl;}int N::B=0;int main(){N P(5),Q(9);N::f1(P);N::f1(Q);return 0;}程序运行结果:A=5B=14A=9B=143.26程序代码:#include<iostream.h>class M{int A;static int B;public:M(int a){A=a;B+=a;cout<<"Constructing"<<endl;}static void f1(M m);~M(){cout<<"Destructing\n";}};void M::f1(M m){cout<<"A="<<m.A<<endl;cout<<"B="<<B<<endl;}int M::B=0;int main(){M P(5),Q(9);M::f1(P);M::f1(Q);return 0;}程序运行结果:ConstructingConstructingA=5B=14DestructingA=9B=14DestructingDestructingDestructing2)#include<iostream.h>class Sample{int a,b;static int c;public:Sample(){a=b=0;c++;}void show(){cout<<"a="<<a<<','<<"b="<<b<<','<<"c="<<c<<endl;}};int Sample::c=1;void main(){Sample a1,a2;a1.show();a2.show();}程序运行结果如下:a=0,b=0,c=3a=0,b=0,c=33)#include<iostream.h>#include<stdio.h>class B{private:int a,b;public:B(){}B(int i,int j){a=i;b=j;}void showB(){cout<<"a="<<a<<","<<'\t'<<"b="<<b<<endl;}};class A{private:B c;public:A(){}A(int i,int j):c(i,j){}void showA(){c.showB();}};void main(){A a1(5,6);a1.showA();}程序运行结果:a=5,b=62.2编写并调试程序。

C 06《友元和常成员》

C  06《友元和常成员》

VC++第六次课 2004.3.17 《友元和常成员》一、友元1、友元函数,①在类中说明,②但不是该类的成员,③允许访问该类的对象的所有成员。

简称友元,关键字friend。

例子:┌──────────────────────────────────┐class Location {private:float X, Y;…………friend float distance(Location &, Location &);};float distance(Location &a, Location &b){float dx = a.X - b.X;float dy = a.Y - b.Y;return sqrt(dx*dx + dy*dy);}└──────────────────────────────────┘优点:①效率,省去调用类的成员函数的开销,②随时通过使用友元增加类的接口。

缺点:破坏了封装性2、友元成员除了自由函数可以说明为友元之外,成员函数也可以说明为另一个类的友元,但要先进行定义性说明。

例子:┌──────────────────────────────────┐class two; //先对two做引用性说明class one {private:int a;public:void func(two &);void func2(..)};class two { //two的定义性说明private:int b;friend void one::func(two &); //友元friend class one; //one是two的友元类};void one::func(two &r){a = r.b;}└──────────────────────────────────┘3、友元类将类one说明为类two的友元类,意味者类one的所有成员函数都是类two的友元函数。

C++实验指导 实验06 const对象和const成员、友元

C++实验指导  实验06 const对象和const成员、友元

实验六、const对象和const成员、友元(2学时)1.实习目的及要求:1)掌握coust对象、 coust成员函数和coust成员数据的使用。

2)掌握友元函数的定义和使用;2.预习:1)预习coust对象及const成员的定义、使用等相关知识。

2)预习友元的概念、友元成员函数、友元类等相关知识;3.实验内容:3.1分析下面的程序,当编译下面的程序后,会出现什么样的错误。

请各位同学用你的学号命名你的作业文件夹,将各题的答案放入(用word文挡或写字板录入均可,要求为每一题建立一个文档),并发到教师机相应目录下(通常是教师机的最后一个硬盘)的作业文件夹中。

具体位置按老师的指示操作。

#include<iostream.h>class Sample{int n;public:Sample(int i){n=i;}void setvalue(int i){n=i;}void display(){cout<<"n="<<n<<endl;}};void main()const Sample s(5);s.setvalue(8); //试图调用非const 成员函数,同时不能改变const 对象中的成员数据 s.display(); //试图调用非const 成员函数,可将其改为const 成员函数}答案:答案见上3.2 编写并调试程序:将各题的源程序(即。

cpp 文件)放入上述的用你的学号命名你的作业文件夹中,并发到教师机相应目录下(通常是教师机的最后一个硬盘)的作业文件夹中。

具体位置按老师的指示操作。

1).编写一个程序求直角坐标中一个点到直线的距离。

要求设计一个点类point , 含有两个公有成员数据x 和y ,代表点的坐标。

另一个类为直线类line ,它有三个 私有成员数据a ,d ,c 。

分别代表直线方程ax+by+c=0的系数。

在类line 中设计一个 友元函数distance 计算一个点到直线的距离。

面向对象程序设计(C++)实验一--类和对象

面向对象程序设计(C++)实验一--类和对象

实验一类和对象一、实验目的:掌握类的设计和对象的创建及相关知识点如对象数组、类聚合、友元函数、静态成员。

二、实验内容:1、设计圆类,求两个圆的位置关系;2、设计圆类和直线类,求直线与圆的位置关系;3、设计学生类,求某班学生成绩的最高分、最低分及平均分;4、设计部门类和教师类,其中部门类成员为教师类的子对象;5、设计家庭银行账户类,其中账户资金为静态数据成员,为家庭成员共享;6、设计复数类,友元函数实现复数的加减。

三、实验过程:1、根据实验题目确定需要设计哪些类、各类中包含哪些数据成员和函数成员,设计各成员的访问权限,设计数据成员的数据类型,设计函数成员的函数原型;2、给出类设计的程序实现,特别要注意重载构造函数的实现;3、在主函数中完成题目中的逻辑,一般情况下需要创建相关类的对象,通过对象对成员函数的调用或者通过对象指针对成员函数的调用完成相应的功能。

四、参考程序代码:1、设计圆类,求两个圆的位置关系#include <iostream>#include <math.h>using namespace std;class Circle{private:float a,b,r;public:Circle(float c,float d,float e){a=c;b=d; r=e;}friend void position(Circle &,Circle &);};void position(Circle &c1,Circle &c2){float n,m,p;p=sqrt((c1.a-c2.a)*(c1.a-c2.a)+(c1.b-c2.b)*(c1.b-c2.b)); n=fabs(c1.r-c2.r);m=c1.r+c2.r;if(p>m)cout << "相离";if(p==m)cout << "相切";if(p<m)cout << "相交";}int main(){float a,b,c,d,e,f;cin >> a >> b >> c >> d >> e >> f ;Circle c1(a,b,c),c2(d,e,f);position(c1,c2);return 0;}运行结果:2、设计圆类和直线类,求直线与圆的位置关系#include<iostream>#include<math.h>using namespace std;class Circle//圆类{private:float x,y,r;public:Circle(float a,float b,float c) {x=a;y=b;r=c;}float getx(){return x;}float gety(){return y;}float getr(){return r;}};class Line//直线类{private:float a,b,c;public:Line(float x,float y,float z){a=x;b=y;c=z;}void position(Circle c1){float d=fabs(a*c1.getx()+b*c1.gety()+c)/sqrt(a*a+b*b) ;//圆心到直线的距离if(d<c1.getr())cout << "相交";if((d-c1.getr())<0.000001)cout << "相切";cout << "相离";}};int main(){Line l1(3,3,4);//创建直线对象Circle c1(-23,3,7);//创建圆对象l1.position(c1);return 0;}运行结果:3、设计学生类,求某班学生成绩的最高分、最低分及平均分#include <iostream>#include <string.h>using namespace std;class Student{private:char name[20],xuehao[20];float math;public:Student(){}Student(char *na,char *xu,float ma):math(ma) {strcpy(name,na);strcpy(xuehao,xu);}void set(char *na,char *xu,float ma){math=ma;strcpy(name,na);strcpy(xuehao,xu);}char *get_name(){return name;}char *get_xuehao(){return xuehao;float get_math(){return math;}};void max_min(Student stu[],int n){Student max,min;max=min=stu[0];for(int i;i<n;i++){if(stu[i].get_math()>max.get_math())max=stu[i];if(stu[i].get_math()<min.get_math())min=stu[i];}cout << "学生成绩最高:" << max.get_name() << "," << max.get_xuehao() << "," << max.get_math() << endl;cout << "学生成绩最低:" << min.get_name() << "," << min.get_xuehao() << "," << min.get_math() << endl;}void ave(Student stu[],int n){float sum=0;for(int i=0;i<n;i++){sum=sum+stu[i].get_math();cout << "ave=" << sum/n;}int main(){char na[20],xu[20];float ma;Student stu[20];int n;cout << "请输入学生总人数"; cin >> n;for(int i=0;i<n;i++){cin >> na >> xu >> ma ; stu[i].set(na,xu,ma); }max_min(stu,n);ave(stu,n);return 0;}运行结果:4、设计部门类和教师类,其中部门类成员为教师类的子对象#include <iostream>#include <string.h>using namespace std;class Department{private:int dep_num;char dep_master[20];char dep_name[20];public:Department(){}Department(int num,char *ma,char *na){dep_num=num;strcpy(dep_master,ma);strcpy(dep_name,na);}void show(){cout << dep_num << "," << dep_master << "," << dep_name ; }};class Teacher{private:char name[20];char haoma[20];Department dep;public:Teacher(char *n,char *nu,int num,char *ma,char *na):dep(num,ma,na) {strcpy(name,n);strcpy(haoma,nu);}void show(){dep.show();cout << "," << name << "," << haoma << endl;}};int main(){Teacher hp("wanghai","12345",6,"kiki","computer");hp.show();return 0;}运行结果:5、设计家庭银行账户类,其中账户为静态数据成员,为家庭成员共享#include <iostream>#include <string.h>using namespace std;class Familymember//家庭成员类{private:char membername[10];//成员名public:static float account;//共享账户资金 Familymember(char *name);static void save(float money);//存钱 static void pay(float money);//支出 static void show(); //显示账户余额};float Familymember::account=0;Familymember::Familymember(char *name) {strcpy(membername,name);}void Familymember:: save(float money) {account= account+money;}void Familymember:: pay(float money){account= account-money;}void Familymember:: show(){cout<<account<<endl;}int main()//主函数{ Familymember husband("wang"),wife("Li"); husband.save(10000);wife.pay(3000);wife.save(5000);wife.show();husband. show();}运行结果:6、设计复数类,友元函数实现复数的加减#include <iostream>using namespace std;class Fushu{private:float ss,xs;public:Fushu(){}Fushu(float a,float b){ss=a;xs=b;}friend Fushu jiafa(Fushu &f1,Fushu &f2){return Fushu((f1.ss+f2.ss),(f1.xs+f2.xs)); }friend Fushu jian(Fushu &f1,Fushu &f2){return Fushu((f1.ss-f2.ss),(f1.xs-f2.xs)); }void show(){cout << ss << " + " << xs << "i" << endl; }};int main(){Fushu f1(2,3),f2(4,5);Fushu f3,f4;f3=jiafa(f1,f2);f4=jian(f1,f2);f3.show();f4.show();return 0;}运行结果:。

友元类的定义和用法

友元类的定义和用法

友元类的定义和⽤法
1.概述
①友元:是定义⼀个类是,该主动声明哪些其他类或函数是它的朋友,进⽽给他们定向提供对类的访问特权。

②友元是C++提供的⼀种破坏数据封装和数据隐藏的机制。

③通过友元将⼀个模块声明为另⼀个模块的友元,⼀个模块能够引⽤到另⼀个模块中本是被隐藏的信息。

④可以使⽤友元函数和友元类。

建议:为了确保数据完整性,及数据封装与隐藏原则,建议尽量不使⽤或少使⽤。

2、友元函数
①友元函数是在类的声明中由关键字friend修饰说明的⾮成员函数,在它的函数体中能通过对象名访问 private和protected 成员。

②作⽤:增加灵活性,使程序员可以在封装和快速性⽅⾯做合理选择。

③访问对象中的成员必须通过对象名。

④友元是单向的。

友元函数的定义⽅法(以定义⼀个Point类为例)
(该函数传⼊引⽤,节约⼯耗)
此时,就会遇到在函数中改变对象私有信息的危险,破坏数据的封装。

例如:
输出:
对⽐原先的输出:
如果想防⽌对象的私有数据被更改 , 可以在传⼊引⽤时加 const修饰例如:
这样在函数中再想更改对象的私有数据时就会报错,例如:
⾄于const的⽤法相信⼤家都见过了,在后⾯的博客中会加以补充。

实验04_类和对象_对象和静态成员

实验04_类和对象_对象和静态成员

实验04.类和对象-对象和静态成员
4.1实验目的
1、理解静态成员(静态数据成员、静态成员函数)的作用与使用;
2、理解友元(友元函数、友元类)的作用于使用;
3、理解常类型的使用;
4.2实验内容
4.2.1程序阅读与调试
1.理解下面的程序,并在Code::Blocks下运行查看结果,回答程序后面的问题。

问题1:以上程序编译能通过吗,为什么?如果不能请修改为能编译通过。

问题2:成员变量nTotalObj在程序中起什么作用,它是如何实现的?
——请将上述问题的解答填写在实验报告对应题号下面。

2.理解下面的程序,并在Code::Blocks下运行查看结果,回答程序后面的问题。

问题1:以上程序存在两处大错误,请分别简要地指出来。

并尝试改正该程序。

——请将上述问题的解答填写在实验报告对应题号下面3.理解下面的程序,并在Code::Blocks下运行查看结果,回答程序后面的问题。

问题1:以上程序存在两处大错误,请分别简要地指出来。

并尝试改正该程序。

——请将上述问题的解答填写在实验报告对应题号下面
4.2.2程序设计
1.某商店经销一种货物。

货物成箱购进,成箱卖出,购进和卖出时以重量为单位,各箱的重量不一样,因此,商店需要记录下目录库存的总重量。

试用C++该程序命名为exp04_p1_1.cpp。

4.3思考题
1、哪些情况必须用到初始化列表?。

实验2 静态成员和友元

实验2 静态成员和友元

淮海工学院计算机科学系实验报告书课程名:《C++程序设计》题目:静态成员和友元班级:学号:姓名:1、实验内容或题目(1)分析调试教材p310页第2题,并修改程序要求允许对日期对象作如下定义:Date d3(d1);//用已有的日期对构造一个新对象。

(2)设计一个点类,其中包括一对坐标数据成员、一个求两点之间距离的友元函数dist和显示坐标点成员函数,并用数据进行测试。

(3)p312页9-11题。

(4)调试分析教材例9.5的运行结果。

2、实验目的或要求(1)熟练掌握构造函数和析构函数的功能和使用方法;(2)掌握友元函数和友元类;(3)掌握成员函数的重载等特性;(4)掌握静态成员和静态成员函数的使用方法。

2、实验步骤与源程序源代码1、1#include <iostream>using namespace std;class Date{public:Date(int,int,int);Date(int,int);Date(int);Date();void display();private:int month;int day;int year;};Date::Date(int m,int d,int y):month(m),day(d),year(y){ }Date::Date(int m,int d):month(m),day(d){year=2005;}Date::Date(int m):month(m){day=1;year=2005;}Date::Date(){month=1;day=1;year=2005;}void Date::display(){cout<<month<<"/"<<day<<"/"<<year<<endl;}int main(){Date d1(10,13,2005);Date d2(12,30);Date d3(d1);Date d4;d1.display();d2.display();d3.display();d4.display();return 0;}1.2#include <iostream>using namespace std;class Date{public:Date(int,int,int);Date(int,int);Date(int);Date();void display();private:int month;int day;int year;};Date::Date(int m,int d,int y):month(m),day(d),year(y) {}Date::Date(int m,int d):month(m),day(d){year=2005;}Date::Date(int m):month(m){day=1;year=2005;}Date::Date(){month=1;day=1;year=2005;}void Date::display(){cout<<month<<"/"<<day<<"/"<<year<<endl;} int main(){Date d1(10,13,2005);Date d2(12,30);Date d3(10);Date d4;d1.display();d2.display();d3.display();d4.display();return 0;}2#include <iostream>#include <cmath>using namespace std;class Point{public:Point (double xx,double yy){X=xx;Y=yy;}int getX(){return X;}int getY(){return Y;}friend float Distance(Point &,Point &); private:int X,Y;};float Distance(Point &p1,Point &p2){double x=double(p1.X-p2.X);double y=double(p1.Y-p2.Y);return (sqrt(x*x+y*y));}int main(){Point p1(3,4),p2(4,5);cout<<"距离为"<<Distance(p1,p2)<<endl;return 0;}3#include <iostream>using namespace std;class Product{public:Product(int n,int q,float p):num(n),quantity(q),price(p){}; void total();static float average();static void display();private:int num;int quantity;float price;static float discount;static float sum;static int n;};void Product::total(){float rate=1.0;if(quantity>10) rate=0.98*rate;sum=sum+quantity*price*rate*(1-discount);n=n+quantity;}void Product::display(){cout<<sum<<endl;cout<<average()<<endl;}float Product::average(){return(sum/n);}float Product::discount=0.05;float Product::sum=0;int Product::n=0;int main(){Product Prod[3]={Product(101,5,23.5),Product(102,12,24.56),Product(103,100,21.5) };for(int i=0;i<3;i++)Prod[i].total();Product::display();return 0;}4using namespace std;class Date;class Time{public:Time(int,int,int);friend void display(const Date &,const Time &); private:int hour;int minute;int sec;};Time::Time(int h,int m,int s){hour=h;minute=m;sec=s;}class Date{public:Date(int,int,int);friend void display(const Date &,const Time &); private:int month;int day;int year;};Date::Date(int m,int d,int y){month=m;day=d;year=y;}void display(const Date &d,const Time &t){cout<<d.month<<"/"<<d.day<<"/"<<d.year<<endl;cout<<t.hour<<":"<<t.minute<<":"<<t.sec<<endl; }int main(){Time t1(10,13,56);Date d1(12,25,2004);display(d1,t1);return 0;}5using namespace std;class Time;class Date{public:Date(int,int,int);friend Time;private:int month;int day;int year;};Date::Date(int m,int d,int y):month(m),day(d),year(y){ } class Time{public:Time(int,int,int);void display(const Date &);private:int hour;int minute;int sec;};Time::Time(int h,int m,int s):hour(h),minute(m),sec(s){ } void Time::display(const Date &d){cout<<d.month<<"/"<<d.day<<"/"<<d.year<<endl;cout<<hour<<":"<<minute<<":"<<sec<<endl;}int main(){Time t1(10,13,56);Date d1(12,25,2004);t1.display(d1);return 0;}6#include <iostream>#include <string>using namespace std;class Student{private:int num;string name;char sex;public:Student(int n,string nam,char s){num=n;name=nam;sex=s;cout<<"Constructor called."<<endl;}~Student(){cout<<"Destructor called."<<endl;}void display(){cout<<"num"<<num<<endl;cout<<"name"<<name<<endl;cout<<"sex"<<sex<<endl;}};int main(){Student stu1(10010,"Wang_li",'f');stu1.display();Student stu2(10011,"Zhang_fun",'m');stu2.display();return 0;}3、测试数据与实验结果(可以抓图粘贴)1.11.22345C++程序设计实验报告64、结果分析与实验体会通过本次作业,在初步了解友元的同时,也发现了一些问题,对以前的一些知识有些遗忘了。

静态成员和友元实验报告

静态成员和友元实验报告
(3)判空,即判断当前栈(即链表)是否为空,也就是判断记录数组中数据元素个数的变量是否为0。
三、概要设计(实现的功能,函数原型及说明等)
应用VC++6.0的编辑环境构造一个类Stack,设计一个整数链表类,实现栈操作。类中需有记录结点个数的数据成员(静态成员),要有判空操作。编制应用程序,取100次随机数(<1000),如果取到的随机数比前一个随机数大的话,入栈,然后逐个取出(即出栈过程)求其和。
对本次试验进行总结:
1.作时应认真仔细。对代码进行分模块测试,
2.应对实验整体架构进行了解。
3.实验操保证其正确性。
4.试验完后对错误进行总结分析。
七、附录(源程序代码,需有相应注释)
#include<iostream>
#include<stdlib.h>
#include <malloc.h>
#include<stdio.h>
return true;
}
int Stack::Pop() //出栈函数
{
SNode *p=new SNode;
int e;
static int count=1;
p=head;
e=p->data;
head=p->next;
free(p);
count++;
return e;
}
int GetSum(Stack &A)求和函数定义
{
count++;
A.Push(x);
cout<<x<<" ";
if(count%10==0)

C++基础-友元专题

C++基础-友元专题

C++基础-友元专题发信站: 南京大学小百合站 (Thu Dec 23 15:46:36 2010)友元友元提供了在不同类的成员函数之间、类的成员函数与一般函数之间进行数据公享的机制。

通过友元关系,一个普通函数或一个类中的成员函数可以访问其他类中的私有和保护成员。

声明为友元的外界对象既可以是不属于任何类的一般函数,也可以是另一个类的成员函数,还可以是整个类(此时该类中的所有成员函数都称为友元函数)。

友元函数在类中说明友元函数的一般格式为:friend <类型><友元函数名>(<参数列表>) ;在<参数列表>中,通常包含一个与该友元函数具有友元关系的类的类型的参数,该参数可以是一般类型、指针类型或引用类型,但通常为引用类型。

友元函数的定义和调用方式与一般函数一样,只是在类中要进行友元声明。

1.友元函数并不是相应类的成员函数,由于它没有隐含的*this指针,所以它不能象成员函数那样直接访问和修改类的成员。

2.友元函数必须在类的定义中说明,其函数体可在类体外定义,也可在类体内定义,在类体外定义时,在函数的前面不要加作用域运算符“::”,也不要加关键字friend,它可以通过参数,或对象访问该类中的所有成员(公有的、私有的和保护的)。

而一般函数只能访问类中的公有成员。

3.友元函数不是类的成员函数,所以不受类中访问权限的限制,可以把它放在类的私有部分、公有部分或保护部分,其作用都是一样的。

4.友元函数不是类的成员函数,所以它的作用域与成员函数不同。

不管在类体外定义还是在类体内定义友元函数,友元函数的作用域都与一般函数的作用域相同。

如例1中的友元函数都具有文件作用域,可在程序中的任何位置调用它。

5.如果类中有指针类型的数据,且用动态方式分配,则在友元函数中该类类型的参数都要是引用类型,否则在运行时会出错。

6.友元函数是一种外部函数访问类中私有成员或保护成员的有效工具,如果使用不当,则是非常危险的。

实验9-静态成员和友元函数

实验9-静态成员和友元函数

淮海工学院计算机工程学院实验报告书课程名:《 C++程序设计》题目:实验九静态成员和友元函数班级:学号:姓名:1、实验内容或题目(1)教材P310第2题,分析程序,写出其运行的输出结果。

(2)P311,第4题。

(3)P312,第9题,(注意:不考虑商店的统一折扣discount)。

(4)P313,第10题。

2、实验目的与要求(1)进一步加深对类和对象的理解。

(2)掌握对象数组、对象的指针及其使用方法。

(3)掌握静态成员和静态成员函数的使用方法。

(4)掌握友元的概念和使用。

(5)了解类模板的使用方法。

3、实验步骤与源程序⑴实验步骤答:读题,回想相关知识点,上机编写程序,并运行修改。

总结知识点,分析出错原因。

⑵源代码第一题#include <iostream>using namespace std;class Date{public:Date(int,int,int);Date(int,int);Date(int);Date();void display();private:int month;int day;int year;};Date::Date(int m,int d,int y):month(m),day(d),year(y){} Date::Date(int m,int d):month(m),day(d){year=2005;}Date::Date(int m):month(m){day=1;year=2005;}Date::Date(){month=1;day=1;year=2005;}void Date::display(){cout<<month<<"/"<<day<<"/"<<year<<endl;}int main(){Date d1(10,13,2005);Date d2(12,30);Date d3(10);Date d4;d1.display();d2.display();d3.display();d4.display();return 0;}第二题//建立一个对象数组,存放五个学生的数据(学号和成绩) //用指针指向数组首元素,输出一.三.五同学数据//建立一个对象数组,存放五个学生的数据(学号和成绩) //用指针指向数组首元素,输出一.三.五同学数据#include <iostream>using namespace std;class Student{ public:Student(int,float);void display();private:int num;float score;};Student::Student(int n,float s):num(n),score(s){} void Student::display(){cout<<num<<" "<<score<<" "<<endl;}int main(){ int i;Student *p;Student stu[5]={Student(1,89.5),Student(2,78),Student(3,86),Student(4,54),Student(5,76)};cout<<"输出第一,第三,第五个同学的数据"<<endl;p=stu;for(i=0;i<3;i++){ p->display();*(p+=2);}return 0;}第三题:#include <iostream>using namespace std;class Goods{ public:Goods(int n,int q,float p):num(n),quantity(q),price(p){};//定义构造函数 void total();static float average(); //声明两个静态公用成员函数static void display();private:int num;int quantity;float price;static float sum; //定义两个静态数据成员static int n;};void Goods::total() //定义非静态成员函数{sum=sum+quantity*price; //计商品总销售款n=n+quantity; //计今日此商品总销售件数}void Goods::display() //定义静态成员函数{cout<<"商品总销售款:"<<sum<<endl;cout<<"每件商品的平均售价:"<<average()<<endl;}float Goods::average() //定义静态成员函数{return(sum/n);} //求商品的平均售价float Goods::sum=0; //以下两行是对静态数据成员初使化int Goods::n=0;int main(){Goods goods[3]={Goods(101,5,23.5),Goods(102,12,24.56),Goods(103,100,21.5)}; //定义对象数组并对其初使化for(int i=0;i<3;i++)goods[i].total();Goods::display(); //调用静态成员函数return 0;}第四题:#include <iostream>using namespace std;class Date; //对Date类的提前引用声明class Time{public:Time(int,int,int);friend void display(const Date &,const Time &); //声明display函数是Time类的友元函数private:int hour;int minute;int sec;};Time::Time(int h,int m,int s) //定义Time类的构造函数{hour=h;minute=m;sec=s;}class Date{public:Date(int,int,int);friend void display(const Date &,const Time &); //声明display函数是Time 类的友元函数private:int month;int day;int year;};Date::Date(int m,int d,int y) //定义Date类的构造函数{month=m;day=d;year=y;}void display(const Date &d,const Time &t) //普通display函数定义{cout<<d.month<<"/"<<d.day<<"/"<<d.year<<endl;cout<<t.hour<<":"<<t.minute<<":"<<t.sec<<endl;}int main(){Time t1(10,12,56); //定义Time类对象t1Date d1(12,25,2004);//定义Date类对象d1display(d1,t1); //调用display函数,实参是Date类对象d1和Time类对象t1return 0;}4、测试数据与实验结果(可以抓图粘贴)第一题:第二题:第三题:第四题:5、结果分析与实验体会。

最新内蒙古科技大学面向对象的程序设计实验6-静态成员和友元

最新内蒙古科技大学面向对象的程序设计实验6-静态成员和友元

内蒙古科技大学面向对象的程序设计实验报告一、实验目的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下运行查看结果,回答程序后面的问题。

C++课件 第十二章 类的其它特性(友元、虚函数、静态成员)

C++课件 第十二章 类的其它特性(友元、虚函数、静态成员)

class Number { public: virtual void add<int a > { cout<<"int a"<<‘\n’; } };
class BigNumber: public Number { public: virtual void add<double a> { cout<<"double a"<<‘\n’; } };
class X { private: char *p; public: X<int size> { p=new char[size]; } virtual ~X< > { delete[ ]p; } //虚析构函数 };
class Y :public X { private: char *pp; public: Y<int sz1, int sz2>: X<sz1> { pp=new char[sz2]; } ~Y< > { delete [ ]pp; } //自动成为虚函数
CAbs *pa; //创建抽象类的指针 //pa->print<>; //错误,因为print<>为纯虚函数,应 去掉
pa->fun<>; //调用抽象类中的非纯函数 CB b; pa=&b; //将抽象类指针指向其派生类 pa->print<>; CC c; CAbs &pb=c; //创建抽象类的引用
只能作为别的类的基类,
不能生成抽象基类的对象
抽象类的作用是:在由该类派生出来的类 体系中,它可对类体系中的任何一个子类提供 一个统一的接口,即用相同的方法对该类体系 中的任一子类实例进行各种操作,并可把接口 和实现分开.

实验二 类与对象

实验二 类与对象

实验二类与对象一、实验目的1、学习类与对象的定义,掌握类与对象的使用方法。

2、学习数据成员与成员函数的访问方式,理解构造函数和析构函数的定义与执行过程,学会构造函数的重载方法。

3、掌握数组与指针的定义与使用方法,理解数组与指针的存储分配与表示。

4、掌握用指针和引用向函数传递参数。

5、掌握静态数据成员和静态成员函数的使用。

6、理解友元与友元函数的作用与使用方法。

二、实验内容1、下面是一个计算器类的定义,请完成该类成员函数的实现。

class Counter{public:Counter(int number);void increment(); //给原值加1void decrement(); //给原值减1int getValue(); //取得计数器值int print(); //显示计数private:int value;};#include<iostream.h>class count{public:counter(int number);void increment();void decrement();int getvalue(int);int print();private:int value;};void count::increment(){int a=value+1;}void count::decrement(){int b=value-1;}int count::getvalue(int s){value=s;return 0;}int count::print(){cout<<value<<"+1="<<value+1<<endl;cout<<value<<"-1="<<value-1<<endl;return 0;}void main(){count s;s.getvalue(5);s.print();}//2、根据注释语句的提示,实现类Date的成员函数。

第五章友元

第五章友元

1、const修饰符的语义是_________。

答案修饰在它左边出现的类型描述符3、下面的类定义了拷贝初始化构造函数,请完成该类的定义和实现。

Class MyClass{public:MyClass(int xx=0,int yy=0){X=xx;Y=yy;}______ ①______ ;___ //拷贝初始化构造函数private:int X,Y;};MyClass::______ ②_________ //拷贝初始化构造函数的实现{X=______ ③______ ;______ ④______ ;}答案①MyClass(MyClass &m)②MyClass(MyClass &m)③m.X ④Y=m.Y4、当需要使用mt修饰的成员函数改变类中的数据成员时,可以使用_________个数据成员。

答案此题不做5、当一个类的成员是某一个类的对象时,该对象就被称为_________。

答案内嵌对象成员6、当一个类对象的成员函数被调用时,该成员函数的_________指向调用它的对象。

答案this指针7、有如下定义语句: MyClass p[10];则系统自动调用该类构造函数___①___次。

当类对象数组p离开它的作用域时,系统自动调用该类析构函数___②___次。

答案10,108、指向数组的指针是指_________。

答案该指针指向一个数组,可以指向任何一个数组元素9、有如下定义语句:MyClass *p[10];,则当类对象数组指针p离开它的作用域时,系统自动调用该类析构函数_________次。

答案010、下列程序通过把类Distance定义为类Point的友元类来实现计算两点之间距离的功能。

请完成该程序。

#include iostream.h>#include <math.h>class Pointpublic:______ ①______ ;Point (______ ②______ ){X=a;Y=b;}void Print(){cout<<"X="<<X<<endl;cout<<"Y="<<Y<<endl;}private:float X,Y;};class Distance{public:float Dis(Point &p,Point &q);};f1oat Distance::Dis(Point &p,Point &q){float result;______ ③______ ;cout<<result<<endl;return result;}void main(){Point p(10,10),q(20,20);Distance d;d.Dis(p,q);}答案11、如果一个类是聚集类,即该类定义了其他类的子对象,则该类的对象和子对象先被初始化的是_________。

友元函数的使用

友元函数的使用

友元函数的使用友元函数的使用友元函数是C++中非常重要的一种函数,作为类之外,但却可以访问类中私有成员和保护成员的函数。

在面向对象的程序设计中,友元函数扮演着非常重要的角色。

本篇文档将对友元函数的使用进行详细介绍。

一、友元函数的定义友元函数是在类的外部声明的一个函数,然后在类中进行声明。

在类声明中,将需要访问类中成员的函数声明为友元函数。

通过这种方式,该函数将具有访问类中私有成员和保护成员的权限。

友元函数可以访问类的所有成员,包括私有成员和保护成员。

语法格式如下:```c++ class A { friend void B();//友元函数 }; ```其中,友元函数B()可以访问A类的私有成员和保护成员。

需要注意的是:在声明友元函数时,不能使用类作为参数类型,因为该函数不属于该类。

但是,可以将该类的对象作为参数类型,以便在友元函数中访问该对象的成员。

二、友元函数的使用在类中定义友元函数的目的是允许多个类之间的相互访问。

友元函数可以与类成员函数一样使用,并可以访问私有和保护成员。

下面是一些使用友元函数的例子。

1.访问私有成员在C++中,私有成员是不能被外部代码直接访问的,而只能被该类的成员函数所访问。

但是,通过使用友元函数,可以将私有成员暴露给其他的代码。

下面是一个使用友元函数访问私有成员的例子。

```c++ #include<iostream> using namespace std; class A { int a;//私有成员 friend void B();//友元函数 };void B() { A obj;cout<<"a="<<obj.a<<endl;//访问私有成员 }int main() { B();//调用友元函数system("pause"); return 0; } ```2.访问多个类中的私有成员如果一个类想要访问另一个类的私有成员,那么可以将该类的成员函数或者友元函数声明为另一个类的友元函数。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

实验5 友元常量成员1.下面是一个完整的Person类的定义,分析代码,了解类的定义以及成员函数的定义方法。

#include <iostream>#include <cstring>using namespace std;class Person{private:char m_strName[20];int m_nAge;int m_nSex;public:Person();//构造函数Person( const char *name, int age, char sex ); //构造函数Person( const Person &p ); //拷贝构造函数~Person() //析构函数{cout<<"Now destroying the instance of Person"<<endl;}void SetName( const char *name );void SetAge( int age );void setSex( char sex );char* GetName();int GetAge();char GetSex();void ShowPerson();};Person::Person() : m_nAge( 0 ), m_nSex( 0 )//构造函数{strcpy( m_strName, "XXX" );}Person::Person( const char *name, int age, char sex ) : m_nAge( age ), m_nSex( sex == 'm'?0:1 )//构造函数{strcpy( m_strName, name );}Person::Person( const Person &p ) : m_nAge( p.m_nAge ), m_nSex( p. m_nSex )//拷贝构造函数{strcpy( m_strName, p.m_strName );}void Person::SetName( const char *name )strcpy( m_strName, name );}void Person::SetAge( int age ){m_nAge = age;}void Person::setSex( char sex ){m_nSex = sex == 'm'?0:1;}char* Person::GetName(){return m_strName;}int Person::GetAge(){return m_nAge;}char Person::GetSex(){return (m_nSex == 0?'m':'f');}void Person::ShowPerson(){cout << GetName() << '\t' << GetAge() << '\t' << GetSex() << endl; }void main(){Person *p1,*p2; //声明两个指向对象的指针p1=new Person; //动态生成一个Person对象cout << "person1: \t";p1->ShowPerson();p1->SetAge( 19 );cout << "person1: \t";p1->ShowPerson();p2=new Person("Zhang3", 19, 'm'); //动态生成一个Person对象cout << "person2: \t";p2->ShowPerson();*p2 = *p1; //对象之间的赋值cout << "person2: \t";p2->ShowPerson();delete p1; //释放p1指针指向对象所占的空间delete p2; //释放p2指针指向对象所占的空间1. 将程序中的各Get函数改为const成员函数,并在main主函数中调用它们来测试程序的正确性。

提示:char* GetName() ;函数原形要改为const char* GetName() const;,考虑为什么?#include <iostream>#include <cstring>using namespace std;class Person{private:char m_strName[20];int m_nAge;int m_nSex;public:Person();//构造函数Person( const char *name, int age, char sex ); //构造函数Person( const Person &p ); //拷贝构造函数~Person() //析构函数{cout<<"Now destroying the instance of Person"<<endl;}void SetName( const char *name );void SetAge( int age );void setSex( char sex );const char* GetName() const;int GetAge() const;char GetSex() const;void ShowPerson();};Person::Person() : m_nAge( 0 ), m_nSex( 0 )//构造函数 //这种是怎么回事啊?{strcpy( m_strName, "XXX" );}Person::Person( const char *name, int age, char sex ) : m_nAge( age ), m_nSex( sex == 'm'?0:1 )//构造函数{strcpy( m_strName, name );}Person::Person( const Person &p ) : m_nAge( p.m_nAge ), m_nSex( p. m_nSex )//拷贝构造函数{strcpy( m_strName, p.m_strName );void Person::SetName( const char *name ){strcpy( m_strName, name );}void Person::SetAge( int age ){m_nAge = age;}void Person::setSex( char sex ){m_nSex = sex == 'm'?0:1;}const char* Person::GetName() const{return m_strName;}int Person::GetAge() const{return m_nAge;}char Person::GetSex() const{return (m_nSex == 0?'m':'f');}void Person::ShowPerson(){cout << GetName() << '\t' << GetAge() << '\t' << GetSex() << endl; }void main(){Person *p1,*p2; //声明两个指向对象的指针p1=new Person; //动态生成一个Person对象cout << "person1: \t";p1->ShowPerson();p1->SetAge( 19 );cout << "person1: \t";p1->ShowPerson();p2=new Person("Zhang3", 19, 'm'); //动态生成一个Person对象cout << "person2: \t";p2->ShowPerson();*p2 = *p1; //对象之间的赋值cout << "person2: \t";p2->ShowPerson();delete p1; //释放p1指针指向对象所占的空间delete p2; //释放p2指针指向对象所占的空间}2. 有以下程序:#include <iostream>using namespace std;class Date; //对Date类的提前引用声明class Time //定义Time类{public:Time(int,int,int);void display(Date &); //display是成员函数,形参是Date类对象的引用private:int hour;int minute;int sec;};class Date //声明Date类{public:Date(int,int,int);friend void Time∷display(Date &); //声明Time中的display函数为友元成员函数private:int month;int day;int year;};Time∷Time(int h,int m,int s) //类Time的构造函数{hour=h;minute=m;sec=s;}void Time∷display(Date &d) //display的作用是输出年、月、日和时、分、秒{cout<<d.month<<“/”<<d.day<<“/”<<d.year<<endl; //引用Date类对象中的私有数据cout<<hour<<“:”<<minute<<“:”<<sec<<endl; //引用本类对象中的私有数据}Date∷Date(int m,int d,int y) //类Date的构造函数{month=m;day=d;year=y;}void main( ){Time t1(10,13,56); //定义Time类对象t1Date d1(12,25,2004); //定义Date类对象d1t1.display(d1); //调用t1中的display函数,实参是Date 类对象d1}请读者分析和运行此程序,注意友元函数Time::display的作用。

相关文档
最新文档