实验4 含有类的静态成员与类的友元的C++程序设计
- 格式:doc
- 大小:47.50 KB
- 文档页数:5
实验4 含有类的静态成员与类的友元的C++程序设计专业:计算机科学与技术班级:10计本1班学号:姓名:实验地点:B102实验时间:2011/11/1 指导教师:李佐勇一、实验目的1.理解类的静态成员解决共享问题的机制;2.掌握类的静态数据成员与静态函数成员的实现方法;3.理解利用友元关系实现数据共享的机制,掌握类的友元函数以及友元类的实现方法;4.学习多文件结构在C++程序中的使用。
二、实验环境一台PC机,Windows XP操作系统,Visual C++ 6.0开发环境。
三、实验内容1.设计一个解决王婆卖瓜问题的程序。
王婆卖瓜,每卖一个瓜,需记录该瓜的重量,还要记录所卖出的总重量和总个数,同时还允许退瓜。
设计一个具有静态数据、函数成员的watermelon类。
实现提示:西瓜类有3个数据成员:重量weight、总重量total_weight以及总个数total_number。
因为不论西瓜是否卖出,总重量total_weight和总个数total_number这两个数据总是要保留的,且这两个数据与单个的西瓜无关联,因此这两个数据要申明为静态数据成员。
成员函数:卖瓜用构造函数模拟,退瓜用析构函数模拟,瓜重用disp成员函数给出屏幕提示。
为了用不与特定对象相联系的静态成员函数来访问静态数据,还需要定义一个显示总重量和总个数的静态成员函数total_disp。
2.设计一个程序,其中有3个类,即CBank、BBank和GBank,分别为中国银行类、工商银行类和农业银行类。
每个类都包含一个私有数据balance,用于存放储户在该行的存款数,另有一个友元函数total用于计算储户在这3家银行中的总存款数。
3. 设计一个程序,其中有2个类,Point类为点类,包含2个私有数据x和y,表示点的坐标,line类为直线类,包含3个私有数据a、b和c,表示直线方程ax+by+c=0。
另有一个友元函数dist,用于计算一个点到直线的距离。
3.2 实验与实践任务3.2.1 实验名称静态成员和友元3.2.2 实验目的1.掌握静态成员的定义和使用。
2.掌握友元的定义和使用。
3.2.3 实验要求1.调试程序要记录调试过程中出现的问题及解决办法;2.编写程序要规范、正确,上机调试过程和结果要有记录,并注意调试程序集成环境的掌握及应用,不断积累编程及调试经验;3.在编写程序时,要按照多文件结构来组织程序。
4.做完实验后给出本实验的实验报告,实验报告的内容包括实验目的、实验内容和结果分析。
3.2.4 实验内容【P1】商店销售某一商品,商店每天公布统一的折扣(discount)。
同时允许销售人员在销售是灵活掌握售价(price),在此基础上,对一次购10件以上者,还可以享受9.8折优惠。
现在已知当天3名销售员的销售情况为:销售员货号(num)销货件数(quantity)销货单价(price)101 5 23.5102 12 24.56103 100 21.5请编程序,计算出当日此商品的总销售款sum,以及每件商品的平均售价。
要求用静态数据成员和静态成员函数【P2】创建一个SavingsAccount类:用static(静态)数据成员包含每个存款人的annualInterestRate(年利率)。
类的每个成员包含一个private数据成员savingsBalance,表示当前存款额。
提供一个calculateMonthlyInterest 成员函数,计算月利息,用savingsBalance乘以annualInterestRate除以12取得,并将当月月息加入savingsBalance。
提供一个静态成员函数modifyInterestRate,将静态annualInterestRate设置为新值。
实例化两个不同的SavingsAccount对象saver1和saver2,余额分别为$2 000.00和$3 000.00 将annualInterestRate设置为3%,计算每个存款人的月息并打印出新的结果。
南昌航空大学实验报告2011年11月9号课程名称:面向对象程序设计B 实验名称:静态成员与友元班级:姓名:同组人:无指导教师评定: 签名:一、实验目的(1)学习静态成员的使用,理解静态成员的特殊用途。
(2)学习友元函数及友元类,领会友元类的作用。
二、实验内容应用VC++6.0的编辑环境构造一个类Stack,设计一个整数链表类,实现栈操作。
类中需有记录结点个数的数据成员(静态成员),要有判空操作。
编制应用程序,取100次随机数(<1000),如果取到的随机数比前一个随机数大的话,入栈,然后逐个取出(即出栈过程)求其和。
用堆分配方法逐个产生满足条件(递增有序)的结点,插入栈中,每当出栈时,要及时将结点删除,求和工作放在类定义外(友元)。
注意:栈中最多会有100个元素,最少会有一个元素,这是由条件(递增有序)决定的。
三、概要设计要实现的功能:构造一个类Stack、设计一个整数链表类,实现栈操作、取100次随机数(<1000),如果取到的随机数比前一个随机数大的话,入栈,然后逐个取出(即出栈过程)求其和。
函数原型为:struct SNode{int data;SNode *next;};class Stack{public:Stack();~Stack();void Push(int e);//insert a data into stackint Pop();//delete a data from stackfriend int GetSum(Stack &);//get sum of stack,friend function//friend class getsum;// get sum of stack,friend class,you can try it using friend classstatic int num;//static numberprivate:SNode *head;};四、详细设计定义类Stack的函数:Stack::Stack(){Head=new SNode;Head->next=NULL;}设计一整数链表类,实现取100次随机数(<1000),如果取到的随机数比前一个随机数大的话,入栈,然后逐个取出的栈操作的函数:void Stack::Push(int e){SNode *p,*q;if(!(p=new SNode))exit(0);p->data=e;q=Head;while(q->next)q=q->next;q->next=p;p->next=NULL;num++;}int Stack::Empty(){return !num;}int Stack::Pop(){int e;if(Empty()){cout<<"The Stack is empty!"<<endl; exit(0);}SNode *p,*q;p=Head;q=p;while(p->next){q=p->next;if(!q->next)break;p=p->next;}p->next=NULL;e=q->data;delete q;num--;return e;}int Stack::GetTop(){int e;if(Empty()){cout<<"The Stack is empty!"<<endl; exit(0);}SNode *p;p=Head;while(p->next){p=p->next;}e=p->data;return e;}求和的函数为:int GetSum(Stack &a){int sum=0,m,tmp;m=a.num;cout<<endl<<"Pop Stack List is:"<<endl;for(int i=0;i<m;i++){tmp=a.Pop();cout<<" "<<tmp;sum+=tmp;}cout<<endl;return sum;}五、程序调试在函数调试的过程中,出现了以下错误提示信息:1、“Stack::Empty”: 函数调用缺少参数列表;请使用“&Stack::Empty”创建指向成员的指针原因为将语句if(Empty())中的括号()漏掉了。
题目1:定义一个复数类,通过重载运算符:*,/,直接实现二个复数之间的乘除运算。
编写一个完整的程序,测试重载运算符的正确性。
要求乘法“*”用友元函数实现重载,除法“/”用成员函数实现重载。
源程序1/*******************第1题*******************//******************单森汉*****************//******************2012-5-1*****************/#include<iostream>using std::cout;using std::endl;class Complex{float Real, Image;public:Complex(float r=0,float i=0) { Real=r;Image=i;}void Show(){cout <<"Real="<<Real<<'\t'<<"Image="<<Image<<'\n';}friend Complex operator *(Complex &, Complex &);Complex operator /(Complex &); //重载运算符+Complex operator +( Complex &);friend Complex operator -(Complex &, Complex &);};Complex operator *( Complex &c1,Complex &c2){Complex t;t.Real=c1.Real * c2.Real - c1.Image * c2.Image;t.Image = c1.Image*c2.Real +c1.Real* c2.Image;return t;}Complex Complex::operator /(Complex &c){Complex t;t.Real =(Real *c.Real+ Image * c.Image)/(c.Real*c.Real+ c.Image * c.Image);t.Image = (Image *c.Real - Real * c.Image)/(c.Real*c.Real+ c.Image * c.Image);return t;}Complex Complex::operator + ( Complex &c){Complex t;t.Real = Real + c.Real;t.Image = Image + c.Image;return t;}Complex operator -(Complex &c1, Complex &c2){Complex t;t.Real=c1.Real-c2.Real;t.Image=c1.Image-c2.Image;return t;}void main(){Complex c1(1,2),c2(3,4),c3;c3=c1*c2;cout<<"两个复数的乘法c3=c1*c2:";c3.Show();c3=c1/c2;cout<<"两个复数的除法c3=c1/c2:";c3.Show();Complex c4(1,2),c5(3,4),c6,c7(1,2),c8(3,0),c9; c6=c4+c5;cout<<"两个复数的加法c6=c4+c5:";c6.Show();c6=c4-c5;cout<<"两个复数的减法c6=c4-c5:";c6.Show();c9=c7+c8;cout<<"一个复数与一个实数的加法c9=c7+c8:"; c9.Show();c9=c7-c8;cout<<"一个复数与一个实数的减法c9=c7-c8:"; c9.Show();}运行结果截图题目2:定义一个向量(一维数组)类,通过重载运算符实现向量之间的加法和减法。
实验4 含有类的静态成员与类的友元的C++程序设计
专业:计算机科学与技术班级:10计本1班学号:姓名:
实验地点:B102实验时间:2011/11/1 指导教师:李佐勇
一、实验目的
1.理解类的静态成员解决共享问题的机制;
2.掌握类的静态数据成员与静态函数成员的实现方法;
3.理解利用友元关系实现数据共享的机制,掌握类的友元函数以及友元类的实现方法;
4.学习多文件结构在C++程序中的使用。
二、实验环境
一台PC机,Windows XP操作系统,Visual C++ 6.0开发环境。
三、实验内容
1.设计一个解决王婆卖瓜问题的程序。
王婆卖瓜,每卖一个瓜,需记录该瓜的重量,还要记录所卖出的总重量和总个数,同时还允许退瓜。
设计一个具有静态数据、函数成员的watermelon类。
实现提示:西瓜类有3个数据成员:重量weight、总重量total_weight以及总个数total_number。
因为不论西瓜是否卖出,总重量total_weight和总个数total_number这两个数据总是要保留的,且这两个数据与单个的西瓜无关联,因此这两个数据要申明为静态数据成员。
成员函数:卖瓜用构造函数模拟,退瓜用析构函数模拟,瓜重用disp成员函数给出屏幕提示。
为了用不与特定对象相联系的静态成员函数来访问静态数据,还需要定义一个显示总重量和总个数的静态成员函数total_disp。
2.设计一个程序,其中有3个类,即CBank、BBank和GBank,分别为中国银行类、工商银行类和农业银行类。
每个类都包含一个私有数据balance,用于存放储户在该行的存款数,另有一个友元函数total用于计算储户在这3家银行中的总存款数。
3. 设计一个程序,其中有2个类,Point类为点类,包含2个私有数据x和y,表示点的坐标,line类为直线类,包含3个私有数据a、b和c,表示直线方程ax+by+c=0。
另有一个友元函数dist,用于计算一个点到直线的距离。
点与直线之间的距离计算公式如下:
2 2b a c
by
ax
d
++
+
=
要求:
①将Point与Line类的定义放在头文件head.h中;
②将Point与Line类的实现部分放在PL.cpp中;
③主函数(类的使用)文件定义为:Lab04_3.cpp。
四、实验记录
1.#include<iostream>
using namespace std;
class watermelon
{
public:
watermelon(double w){
weight=w;
total_weight+=w;
total_number++;
}
~watermelon(){
total_weight-=weight;
total_number--;
}
static void total_disp(){
cout<<"Now total weight is:"<<total_weight<<endl;
cout<<"Now total number is:"<<total_number<<endl;
}
void disp(){
cout<<"The weight is:"<<weight<<endl;
}
private:
double weight;
static double total_weight;
static int total_number;
};
double watermelon::total_weight=0.0;
int watermelon::total_number=0;
void main(){
watermelon W1(25.8);
W1.disp();
watermelon::total_disp();
watermelon W2(23.5);
W2.disp();
watermelon::total_disp();
watermelon W3(36.2);
W3.disp();
watermelon::total_disp();
}
2. #include<iostream>
using namespace std;
class CBank
{
public:
friend int total();
CBank()
{
int w=10000;
balance=w;
}
private:
int balance;
};
class BBank
{
public:
friend int total();
BBank()
{
int w=20000;
balance=w;
}
private:
int balance;
};
class GBank
{
public:
friend int total();
GBank() {
int w=30000;
balance=w;
}
private:
int balance;
};
int total(){
CBank a;
BBank b;
GBank c;
int balance;
balance=a.balance+b.balance+c.balance;
return balance;
}
void main(){
int cunqian;
cunqian=total();
cout<<"The saving number is: "<<cunqian<<endl;
}
3.
//head.h
class line;
class point
{
public:
point(int x,int y);
friend double dist(point &p,line &l);
private:
int x,y;
};
class line
{
public:
line(int a,int b,int c);
friend double dist(point &p,line &l);
private:
int a,b,c;
};
//PL.cpp
#include"head.h"
#include<iostream>
#include<cmath>
using namespace std;
point::point(int x1,int y1){
x=x1;y=y1;
}
line::line(int a1,int b1,int c1){
a=a1;b=b1;c=c1;
}
double dist(point &p,line &l){
cout<<"x="<<p.x<<",y="<<p.y<<endl;
cout<<"a="<<l.a<<",b="<<l.b<<",c="<<l.c<<endl;
double t=sqrt(l.a*l.a+l.b*l.b);
return abs(l.a*p.x+l.b*p.y+l.c)/t;
}
//lab04_3.cpp
#include"head.h"
#include<iostream>
#include<cmath>
using namespace std;
int main(){
point p1(4,5);
line l1(3,4,5);
cout<<dist(p1,l1)<<endl;
return 0;
}
五、思考题
1.类与结构体的区别?
答:在c里结构体只能定义数据成员,不能有函数成员,但可以定义函数指针来模拟函数。
在C++中,结构体和类除了默认的访问方式和默认的继承方式不同外,其它都一样。
结构体默认是公有,类默认是私有
2.类的静态成员函数可以通过对象名调用吗?
答:静态成员函数可以直接访问该类的静态数据和函数成员。
而访问非静态成员,必须通过对象名。
六、实验小结。