实验4 含有类的静态成员与类的友元的C++程序设计
C++语言程序设计实验4(类和对象)

是:用初始对象的每个数据成员的值,初始化将要建立的对象的对应数据成员。
构造函数和拷贝构造函数的声明格式如下:
class 类名
{
public: 类名(形参); 类名(类名 &对象名);
//构造函数 //拷贝构造函数
... ...
}; 类名::类名()
//构造函数的实现
{ 函数体;
} 类名::类名(类名 &对象名)
6. 本章小结
本章主要介绍了面向对象的基本概念、类和对象的声明、构造函数、析构函数、内联成 员函数、拷贝构造函数、类的组合。
类是面向对象程序设计中最重要、最基本的概念,也是学习面向对象方法时遇到的第 1 个难点。类是对逻辑上相关的函数和数据的封装,是对问题的抽象描述。
要理解类与对象,必须要结合实例来学习,读者可以思考:除了书中列出的例子,现实 世 界 中 还 有 哪 些 有 形 或 无 形 的 事 务 可 以 被 抽 象 为 程 序 中 的 类 ,每 个 类 又 存 在 哪 些 对 象( 实 体 )。 这样可以对类的概念了解的快一些。
本章开始的每章的最后有一个实例——人员信息管理程序,这个例子贯穿后续各章,利 用每章介绍的只是不断丰富程序的功能,建议课后仔细阅读、体会,并尝试修改、补充程序 的功能。
另外,本章中还介绍了利用 UML 语言表示类与对象的方法,以后各章还将进一步介绍 用 UML 语言表示类之间的关系,但这远不是 UML 语言的全部,这方面的内容也不是初学者 学习的重点,读者可以不必深究,了解一下就可以了。如果有需要,可以另外学习软件工程 的课程。
面向对象的程序设计目的是:实现软件设计的产业化。主要观点是认为自然界是由实体 (对象)所组成。程序设计的出发点是:使用面向对象的观点来描述模仿并处理现实问题。 他要求:高度概括、分类、抽象。
C++面向对象程序设计第六章静态成员与友员

5
6.1.1 静态数据成员 类的非静态数据成员在类的每一个对象中都拥有一 个拷贝,即每个对象的同名数据成员可以分别存储 不同的数值。 静态数据成员是类的数据成员的一种特例,每个类 只有一个静态数据成员拷贝,它由该类的所有对象 共同使用和维护,从而实现了同一个类的不同对象 之间的数据共享。 静态数据成员不是属于某个对象的,而是属于类的, 它由某个类的所有对象所共有。 因为每个类只有一个静态数据成员拷贝,所以在存 储方面节省内存,并且它的值对每个对象都是一样 的。 只要对静态数据成员的值进行更新,所有对象的该 静态数据成员的值都被更新为相同的值。
【例6.8】 一个类作为另一个类的友元举例 】
16
6.2.3 友元类 在使用友元时,需要注意的是: 友元关系不是双向的,即如果将类A说明为类B的 友元,那么类A的成员函数就可以直接访问类B的 私有成员,但反过来类B成员函数就不可以直接 访问类A的私有成员。 友元关系也不是传递的,即类B是类A的友元,类 C是类B的友元,而类C不是类A的友元。除非将 类C说明为类A的友元,这时类C和类A之间才存 在友元关系。 由于友元关系破坏了类的封装性、降低了类的可 靠性和可维护性,所以不要滥用友元关系。 友元关系是不被继承的。
rear
18
【例6.1】 私有静态数据成员使用举例(P171)
#include <iostream.h> class sample {public: sample (int i,int j); void printnumber( ); int printsum( ); private: int a,b; static int sum; }; int sample::sum=0; sample::sample (int i,int j) { a=i; b=j; sum+=a+b; } void sample::printnumber( ) {cout<<a<<","<<b<<endl;} int sample::printsum( ) { return sum; } void main( ) { sample x(1,2),y(3,4); x.printnumber( ); y.printnumber( ); cout<<x.printsum( )<<endl; cout<<y.printsum( )<<endl; }
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; //创建抽象类的引用
只能作为别的类的基类,
不能生成抽象基类的对象
抽象类的作用是:在由该类派生出来的类 体系中,它可对类体系中的任何一个子类提供 一个统一的接口,即用相同的方法对该类体系 中的任一子类实例进行各种操作,并可把接口 和实现分开.
实验4 含有类的静态成员与类的友元的C++程序设计

实验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,用于计算一个点到直线的距离。
静态成员和友元

Student::Student(char* name)
: m_pNext(NULL),
m_pPrev(NULL)
{ … // 每构造一个对象,学生总 // 数应该加1 ++s_nStudentCount;
assert(&s.s_nCount==&Student::s_nCount); }
6.2 静态数据成员-唯一性
设置全局变量来保存链表头指针和学生总数 的作法可行,但是不够安全,因为程序的任 何地方都可以修改这两个变量(导致程序的行 为异常)。
【演示】
6.1 静态成员-引入
可以使用静态成员解决上述问题。 静态成员包括两种:
静态数据成员:使用关键字static修饰的数据成员。 静态成员函数:使用关键字static修饰的成员函数。
void main() // 通过对象访问私有非静态成员,OK
class Vector
m_pPrev
Student* m_pLeader; // OK
{ Student(char* name);
void RemoveFromList(Node* pHead, Node* pToDelete );
4 示例-对S演t示u1d的e改n进t* p1 = new Student(“a”);
Student* q = s_pListHead;
extern iSnttgu_ndCeounntt;* m_pNext;
Student* m_pPrev; void AddToList( Node* pHead,Node* pToInsert);
//error LNK2001: unresolved external symbol "int g_nCount"
实验4 静态成员与友元

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%,计算每个存款人的月息并打印出新的结果。
C++ 第三章 类和对象的进一步讨论(四)

两个整数比较的类
class Compare_int // 比较两个整数的类 {private: int x,y; public: Compare_int(int a,int b) {x=a;y=b;} int max() {return (x>y)?x:y;} int min() {return (x<y)?x:y;} };
2. 友元成员函数
例: 将成员函数声明为友元函数 例子中有两个类Time和Date。其中 例子中有两个类 和 。其中Time类 类 里定义成员函数 void display(Date &) , 它除了显示时间外还要显示日期, 它除了显示时间外还要显示日期,这个日 期通过引用形参访问。 期通过引用形参访问。 类中将Time类的 display成员函数 在Date类中将 类中将 类的 成员函数 定义为友元函数,允许display访问 Date类 定义为友元函数,允许 访问 类 的所有私有数据成员。 的所有私有数据成员。
例
判断以下输出 #include <iostream> #include <string> using namespace std; int max(int a,int b) { return (a>b)?a:b; } int main() { cout<<max(10,20); cout<<max(10.5,20.5); return 0; }
说明
静态数据成员不属于某一个对象,不占用对象空 静态数据成员不属于某一个对象, 间,而是在所有对象外单独开辟空间 静态数据成员是在程序编译时分配空间, 静态数据成员是在程序编译时分配空间,到程序 结束时才释放空间, 结束时才释放空间,不随着对象的建立而分配空 间,也不随着对象的撤消而释放空间 静态数据成员可以初始化, 静态数据成员可以初始化,但只能在类体外进行 初始化,形式为: 初始化,形式为:
C++实验报告四--静态成员与友元

南昌航空大学实验报告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、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验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.类的静态成员函数可以通过对象名调用吗?
答:静态成员函数可以直接访问该类的静态数据和函数成员。
而访问非静态成员,必须通过对象名。
六、实验小结。