静态成员函数与友元
- 格式:doc
- 大小:90.00 KB
- 文档页数:4
复习:C++填空题1.C++的流库预定义了4个流,它们是cin、cout、clog 和___。
答案:cerr [解析]分别是标准输入、输出、标准错误流(缓冲)和标准错误流 (无缓冲标准错误)2.每个对象都是所属类的一个___。
答案:实例3.在已经定义了整型指针p后,为了得到一个包括10个整数的数组并由p所指向,应使用语句___。
答案: int *p=new int[10];4.函数模板中紧随template之后尖括号内的类型参数都要冠以保留字___。
答案:class [解析]类模板template <class T1,class T2,...,class Tn>5.定义类的动态对象数组时,系统只能够自动调用该类的___构造函数对其进行初始化。
答案:无参[解析]使用new创建对象数组,调用无参构造函数。
6.表达式cout<<end1 还可表示为___。
答案:‘\n’[解析]endl与字符常量‘\n’等价。
7.在C++中,访问一个指针所指向的对象的成员所用的指向运算符是___。
答案:->[解析]指针使用成员方法:“->”指向运算符和“.”成员访问运算符。
8.假如一个类的名称为MyClass,使用这个类的一个对象初始化该类的另一个对象时,可以调用___构造函数来完成此功能。
答案:复制或拷贝[解析]复制或拷贝构造函数就是用对象初始化新的对象。
9.对赋值运算符进行重载时,应声明为___函数。
答案:类成员 [解析]运算符重载的方法有友元或者成员函数两种途径,但是赋值运算符只能使用成员函数的方法来实现。
10.如果要把A类成员函数f()且返回值为void声明为类B的友元函数,则应在类B的定义中加入的语句___。
答案:friend void A::f();[解析]成员函数作为另一个类的友元函数,格式为:friend 返回类型 类名::函数(形参)。
11.String 类的___方法返回查找到的字符串在主串的位置。
1.友元函数的简单介绍1.1为什么要使用友元函数在实现类之间数据共享时,减少系统开销,提高效率。
如果类A中的函数要访问类B中的成员(例如:智能指针类的实现),那么类A中该函数要是类B的友元函数。
具体来说:为了使其他类的成员函数直接访问该类的私有变量。
即:允许外面的类或函数去访问类的私有变量和保护变量,从而使两个类共享同一函数。
实际上具体大概有下面两种情况需要使用友元函数:(1)运算符重载的某些场合需要使用友元。
(2)两个类要共享数据的时候。
1.2使用友元函数的优缺点1.2.1优点:能够提高效率,表达简单、清晰。
1.2.2缺点:友元函数破环了封装机制,尽量不使用成员函数,除非不得已的情况下才使用友元函数。
2.友元函数的使用2.1友元函数的参数:因为友元函数没有this指针,则参数要有三种情况:2.1.1 要访问非static成员时,需要对象做参数;2.1.2 要访问static成员或全局变量时,则不需要对象做参数;2.1.3 如果做参数的对象是全局对象,则不需要对象做参数;2.2友元函数的位置因为友元函数是类外的函数,所以它的声明可以放在类的私有段或公有段且没有区别。
2.3友元函数的调用可以直接调用友元函数,不需要通过对象或指针2.4友元函数的分类:根据这个函数的来源不同,可以分为三种方法:2.4.1普通函数友元函数2.4.1.1 目的:使普通函数能够访问类的友元2.4.1.2 语法:声明:friend + 普通函数声明实现位置:可以在类外或类中实现代码:与普通函数相同调用:类似普通函数,直接调用2.4.1.3代码:class INTEGER{friend void Print(const INTEGER& obj);//声明友元函数 };void Print(const INTEGER& obj){//函数体}void main(){INTEGER obj;Print(obj);//直接调用}2.4.2类Y的所有成员函数都为类X友元函数—友元类2.4.2.1目的:使用单个声明使Y类的所有函数成为类X的友元,它提供一种类之间合作的一种方式,使类Y的对象可以具有类X和类Y的功能。
实验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,用于计算一个点到直线的距离。
静态成员函数静态成员函数是指在类中声明的用static关键字修饰的函数,也叫作类函数。
一般来说,它不需要访问类的数据成员,它只可以调用类的静态成员函数和友元函数,不可以调用普通成员函数,但它可以调用其他所有的成员函数。
静态成员函数也可以用于构造函数那里,因为只有静态成员函数没有隐式的this指针,所以,静态成员函数无法访问非静态成员数据。
二、静态成员函数的作用1、它可以实现自定义的初始化及赋值,所有的对象在创建时都使用相同的初始化及赋值,这样可以节省很多时间。
2、用它可以实现全局函数的功能,但与全局函数不同的是,它可以访问类的private部分。
3、它可以提供对象的总数,通过静态友元函数来实现,可以检测构造函数和析构函数的调用次数,从而检测对象的数量。
4、它可以返回类的静态成员变量,也可以用于类的计算,这种方法可以使我们不必使用全局变量。
三、静态成员函数的特点1、只有在类中才能使用静态成员函数,而不能直接在主程序中使用它们。
2、它可以调用类中所有的静态成员函数,但不能调用普通成员函数。
3、它不能操作类的非静态成员数据,但可以调用其他所有的成员函数。
4、它只能被类的静态成员函数和友元函数调用。
四、实例下面我们来看一个使用静态成员函数的实例,这个实例演示了如何使用静态成员函数来访问类的静态成员变量。
#include <iostream>using namespace std;class StaticClass{private:static int count;public://静态成员函数static int getCount(){return count;}//普通成员函数void setCount(int val){count = val;}};//静态变量初始化int StaticClass::count = 0;int main(){//设置count的值StaticClass::setCount(5);//获取count的值cout<<count的值为:<<StaticClass::getCount()<<endl;return 0;}上面的程序中,定义了一个静态变量count,在类外面定义了这个静态变量,指定了它的初值为0,在类中定义了一个静态成员函数getCount(),用于访问静态变量count,这里不用构造函数,也没有实例化任何对象,只要使用类名来调用静态成员函数就可以使用私有成员count,并且可以通过它获取静态变量count的值,并将这个值输出在屏幕上。
对象(object):类(class):!在声明类的时候注意大括号后面的分号;!访问类中的私有成员属性,必须通过对象调用共有成员函数对私有属性进行访问。
对象访问要用‘.’,对象的引用访问要用‘->’。
封装和信息隐藏(encapsulation and information hiding):构造函数:形式:一般为公有成员函数,构造函数与类名相同,无返回值甚至没有void,可以带参数,可以重载。
拷贝构造函数:深拷贝:在拷贝时会申请内存空间,浅拷贝:只是指向同一个地址,不会申请空间。
当调用拷贝构造函数有返回值时,相当于重新构造了一个对象,若没有分配空间,默认是浅拷贝,即没有分配空间,因此在析构的时候会出问题。
析构函数:形式:在构造函数前面加上‘~’,不可以重载,不带参数,不能有返回值,不指定函数类型。
内联函数:在类中直接定义函数体,在成员函数进行编译时,是作为内联函数实现的。
功能:为了提高效率的,空间换时间,在预处理时进行替换注意:内联函数里面代码1~5行,不能含有for,switch,while等控制语句,其次在声明为内联函数后,函数也不一定会将作为内联函数,具体还有看代码的复杂度。
友元函数:是定义在类外部的普通函数,其特点是能够访问类中的私有和保护成员,类的访问限制对其不起作用。
友元函数必须在类中声明。
注意:友元函数会破坏类的封装性,友元函数不是成员函数,用法与普通函数一样。
友元函数只能用对象名引用类中的数据成员。
即函数参数必须是对象,不带有this指针。
友元类:静态数据成员:若把一个类的某个数据成员设置为静态的,则由该类产生的所有对象,其静态成员都共享一个存储空间,这个空间是在编译时决定的。
在说明对象时,并不为静态类型的成员分配空间。
int A::z=0;静态成员函数:在函数前面加上static修饰,静态成员只能访问类中的静态数据成员和静态成员函数,不能直接访问类中的非静态数据(可以通过引用),静态成员函数可以被其他程序的代码直接调用,所以它不包含对象地址的this指针。
HZAU-专业C++作业11-12判断题1. 友元关系是单向的,不可交换的。
(2分)2. 只有成员函数才能传递this指针,而友元函数不能传递this指针(2分)3. 友元函数是成员函数,它可以访问类中私有成员。
(2分)4. 在成员函数中访问对象的数据成员时,可以直接用数据成员名,而在友员函数中访问对象的数据成员时,必须指明是哪个对象的数据成员。
(2分)5. 友元是可以继承的。
(2分)6. 常成员函数只能用来引用数据成员的值,而不允许改变数据成员的值。
(2分)7. C++语言允许使用友元,但是友元会破环封装性。
(2分)8. 必须在类定义体外对静态数据成员进行初始化。
(2分)9. 能访问一个类CMyClass中的private成员的可以是类CMyClass 的成员函数,友元函数和友元类中的函数。
(2分)10. 类的友元函数是指可以访问本类私有成员的其他类的成员函数。
(2分)11. 类中的静态成员数据为该类的所有对象所共享,并且,在该类对象被撤销时,静态成员并没有撤销。
(2分)12. 如果在一个类的对象之间要进行数据交换,可以使用该类的静态数据成员来完成。
(2分)13. 如果一个类的所有对象都共享某一个变量,则应当将该变量定义为该类的私有成员。
(2分)1.如果类A被说明成类B的友元,则()。
(2分)A. 类A的成员即类B的成员B. 类B的成员即类A的成员C. 类A的成员函数不得访问类B的成员D. 类B不一定是类A的友元2.友元的作用()。
(2分)A. 提高程序的运用效率B. 加强类的封装性C. 实现数据的隐藏性D. 增加成员函数的种类3.下述静态数据成员的特征中,()是错误的。
(2分)A. 静态数据成员要在类体外进行初始化B. 引用静态数据成员时,要在静态数据成员名前加<类名>和作用域运算符C. 静态数据成员不是所有对象所共用的D. 说明静态数据成员时前边要加修饰符static已知类A是类B的友元,类B是类C的友元,则()。
C++语言程序设计复习题《c++程序设计》复习题一、多项选择题1.所谓数据封装就是将一组数据和与这组数据有关操作组装在一起,形成一个实体,这实体也就是()a、 B类,对象C,函数体D,数据块2。
面向对象编程语言的关键元素是()a、抽象和封装b、抽象和多态性c、抽象,封装,继承和多态性D,抽象,封装和继承3。
在定义类的()a、成员函数B、数据成员C、对象D和友元函数时,会自动调用并执行类的构造函数4.设有函数模板templateqsum(qx,qy){return(x)+(y);}以下语句中函数模板的错误使用是()a、sum(10,2);b、sum(5.0,6.7);c、总和(15.2f,16.0f);d、总和(ab、cd);5.假设A类是B类的朋友,B类是C类的朋友,那么()A类必须是C类的朋友,B类必须是A类的朋友c、类c的成员函数可以访问类b的对象的任何成员d、类a的成员函数可以访问类b的对象的任何成员6.静态成员函数没有()a、返回值b、this指针c、指针参数d、返回类型7.当一个类的某个函数被说明为virtual时,该函数在该类的所有派生类中(a、都是虚函数b、只有当它被重新解释时,它才是一个虚拟函数c、只有被重新说明为virtual时才是虚函数d、都不是虚函数8.以下描述不正确:(a)派生类通常使用公共派生b、对基类成员的访问必须是无二义性的c、赋值兼容规则也适用于多重继承的组合d、基类的公有成员在派生类中仍然是公有的9.在c++中实现封装是借助于())a、枚举C,数组B,类D,函数10.所有在函数中定义的变量,都是()a、全局变量b、局部变量c、静态变量d、寄存器变量11.下列特性中,c与c++共有的是()a、继承B、封装C、多态性D和函数定义不能嵌套12。
一般来说,函数模板中类型参数的个数不能是()a、0b、2C、4D和313.在下列成对的表达式中,运算符“+”的意义不相同的一对是()a、5.0+2.0和5.0+2c、5.0+2.0和5+2b、 5.0+2.0和5+2.0D、5+2.0和5.0+214.类的指针成员的初始化是通过函数完成的,这个函数通常是()a、析构函数b、构造函数c、其它成员函数d、友元函数15.禁止修改指针P本身和P指向的数据。
题目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:定义一个向量(一维数组)类,通过重载运算符实现向量之间的加法和减法。
C++语言程序设计填空基础练习题1.假设int a=1,b=2;则表达式(++a/b)*b--的值为_____。
2. 抽象类中至少要有一个___函数。
3. 一个抽象类的派生类可以实例化的必要条件是实现了所有的___。
4. 下面程序的输出结果为_____。
#include <iostream.h> void main() {int num=2,i=6; do {i--;num++; }while(--i); cout<<num<<endl;}5. 静态成员函数、友元函数、构造函数和析构函数中,不属于成员函数的是_____。
6. 在用C++进行程序设计时,最好用_____代替malloc。
7. 由const修饰的对象称为_____。
8. 在C++程序设计中,建立继承关系倒挂的树应使用_____继承。
9. 基类的公有成员在派生类中的访问权限由_____决定。
10. 不同对象可以调用相同名称的函数,但执行完全不同行为的现象称为_____。
11. this指针始终指向调用成员函数的_____。
12. 预处理命令以_____符号开头。
13. 类模板用来表达具有_____的模板类对象集。
14. C++程序的源文件扩展名为_____。
15. 在#include命令中所包含的头文件,可以是系统定义的头文件,也可以是_____的头文件。
16. vector类中向向量尾部插入一个对象的方法是_____。
17. C++语言中如果调用函数时,需要改变实参或者返回多个值,应该采取_____方式。
18. 语句序列 ifstream infile; infile.open(“data.dat”);的功能可用一个语句实现,这个语句是_____。
19. 如果要把类B的成员函数void fun()说明为类A的友元函数,则应在类A中加入语句_____。
20. 在编译指令中,宏定义使用___指令。
c++this指针的用法
this指针是每个对象都隐含着的,一个指向对象本身的指针,因为对象本身在函数中作为参数传入,有this指针就可以更好的处理类的函数。
C++中this指针的用法有以下几种:
1、在成员函数中访问成员变量:在成员函数中,如果我们使用this指针,则可以避免因局部变量名和成员变量名重复而引起的错误。
2、在成员函数中传递指向自身的指针:我们使用this指针即可传递一个指向自身的指针,这个指针可以在其它的函数中被使用。
3、用在静态成员函数中:当静态成员函数被调用时,this指针不会自动生成,因此我们只能在静态成员函数中使用this指针。
4、在调用友元函数是使用:由于友元函数不属于任何类,因此无法自动获得this 指针,此时,如果我们需要使用this指针,可以通过显示地将this指针作为参数传递给友元函数。
实验三静态成员和友元函数实验名称:静态成员和友元函数学时安排:2实验类别:设计性实验实验要求:1人1组一、实验目的和任务1)熟练掌握友元函数设计的方法2)掌握友元函数的含义,友元函数和成员函数的区别。
二、实验原理介绍根据要求正确定义静态成员和友元函数。
将别的模块声明为友元,使类中本隐藏的信息如私有和保护成员就可以被友元访问。
三、实验设备介绍软件需求: Visual C++ 6.0硬件需求: 对于硬件方面的要求,建议配置是Pentium III 450以上的CPU处理器,64MB 以上的内存,200MB的自由硬盘空间、CD-ROM驱动器、能支持24位真彩色的显示卡、彩色显示器、打印机。
四、实验内容和步骤【实验3-1】静态成员为账户类ACCOUNT增加静态成员count和 InterestRate表示账户数量和利率,增加静态成员函数GetCount返回账户数目 GetInterestRate返回银行利率class ACCOUNT {public:ACCOUNT(string accno,string name,float balance);~ACCOUNT();void Deposit(float amount);void Withdraw(float amount);float GetBalance();void Show(void);static int GetCount();static float GetInterestRate();private:static int count;static float InterestRate;string _accno,_accname;float _balance;};【实验3-2】友元函数为账户类ACCOUNT增加一个友元函数,实现账户结息,要求输出结息后的余额(不计算利息税),并在main函数中调用进行测试。
friend void Update(ACCOUNT& a);【实验3-3】(加分题)在main函数中,设计一个ACCOUNT类型的数组,为数组中的10个对象初始化,并调用成员函数测试存款、取款、显示等函数,再调用友元函数测试进行结息。
友元成员函数C++言是一种面向对象的编程语言,它为程序员提供了一系列强大的特性和功能。
友元成员函数是C++中一种重要的概念,它可以让对象访问其他对象的私有成员。
友元成员函数的实现机制可以帮助程序员有效的处理一些私有成员的访问问题。
所谓的友元成员函数,即不是成员函数,也不是非成员函数,而是一种特殊的函数,它既不属于某一个类的成员函数,也不属于非成员函数,而是属于友元函数。
友元函数可以访问对象的私有成员,它可以用来访问两个类之间的成员,因此它是一种函数特性,它可以用来访问受保护成员和私有成员。
友元成员函数的语法格式有以下几类形式:(1)声明友元函数:类名::friend数名(参数列表);(2)声明友元类:friend class名;(3)重载运算符:friend名 operator算符(参数列表);在实际应用中,友元成员函数可以帮助程序员有效的处理私有成员的访问问题,并保护私有成员不受外界影响。
除此之外,友元成员函数还可以提高代码的可读性,将复杂性隐藏起来,从而使代码更简洁,更易于管理。
不过,在使用友元成员函数时,程序员也需要特别注意。
首先,友元函数的声明和定义必须位于友元函数的作用域内,并且需要注意友元函数的参数定义。
其次,友元函数不能访问类的私有成员,也不能调用类的构造函数。
最后,友元函数不能改变类的私有成员的值,只能读取其值。
此外,友元函数也不能修改类的静态变量。
使用友元成员函数既可以拓展类的功能,也可以提高类的可读性。
但是,程序员在使用友元成员函数时,需要特别注意以上几点,同时也要谨慎使用,以避免程序出现不可预料的错误。
总之,友元成员函数是C++中一种重要的概念,它可以帮助程序员有效的处理私有成员的访问问题,并可以拓展类的功能和提高类的可读性,但是程序员在使用友元成员函数时,也要注意以上几点,以避免出现不可预料的错误。
友元函数的声明和定义友元函数是一种特殊的函数,它可以访问类的私有成员和保护成员。
友元函数可以在类的外部定义,但是必须在类的内部进行声明。
下面我们来详细介绍友元函数的声明和定义。
友元函数的声明在类的定义中,我们可以使用关键字“friend”来声明一个友元函数。
语法如下:```class MyClass {friend void myFriendFunction();};```上面的代码声明了一个名为“myFriendFunction”的友元函数。
这个函数可以访问MyClass类的所有成员,包括私有成员和保护成员。
在声明友元函数时,我们并不需要指定类的作用域,因为友元函数并不属于类的成员函数。
但是,我们可以在类的内部使用类名限定友元函数的作用域。
例如:```class MyClass {public:friend void myFriendFunction() {// 可以访问MyClass的所有成员};```上面的代码定义了一个名为“myFriendFunction”的友元函数,并在该函数中通过类名访问了MyClass的成员。
友元函数的定义友元函数的定义与普通函数的定义类似。
我们可以在类的外部定义一个友元函数,并在函数前面加上类名和作用域解析符号“::”。
例如:```class MyClass {friend void myFriendFunction();};void MyClass::myFriendFunction() {// 可以访问MyClass的所有成员}```上面的代码定义了一个名为“myFriendFunction”的友元函数,并在函数前面加上了类名和作用域解析符号“::”。
需要注意的是,友元函数并不属于类的成员函数,因此它没有this指针。
因此,在友元函数中无法访问类的非静态成员。
但是,我们可以通过类名限定的方式访问静态成员。
例如:class MyClass {static int myStaticMember;friend void myFriendFunction();};void MyClass::myFriendFunction() {int value = MyClass::myStaticMember;}```上面的代码定义了一个名为“myFriendFunction”的友元函数,并在函数中通过类名访问了MyClass的静态成员myStaticMember。