友元函数 运算符重载 const static
1、友元函数
在类中一般的成员函数具备:
(1)、该函数能访问类中的私有部分
(2)、该函数位于类的作用域之中
(3)、该函数必须经由一个对象去激活,也就是说有一个this指针;
友元函数不同之处:
(1)、在#include<iostream> using namespace std;的前提下,必须的类外先声明;
classTest;voidfun();//有元函数的声明
但是在#include<iostream.h>中不用这个有元函数的声明;这是早期头文件的包含。
(2)、在类内必须声明是朋友,friend(关键字),函数声明
classTest{friendvoidfun();//朋友没有公有,私有,保护之分,所以限定修饰符在这不起任何作用};
(3)、在类外实现方法的定义,此时不用再加friend了;
voidfun(){..........}
有元函数具有的特性:该函数能访问类的私有数据;不是该类的成员函数,也不需要对象驱动;
还有友元类,跟其使用一样,类中所有函数均可调用其朋友的私有数据;
2、运算符的重载(个人认为C++中运算符的重载很有用,也很重要)
相当于函数的调用,对其的另一种更加人文化的解释,并告诉 C++编译器,遇到该重载运算符时调用此函数。
定义运算符重载的一般格式:
返回值类型 类名::operator重载的运算符(参数列表);
假如出现复数类:
Complex{public:.....private:intreal;intp_w_picpath;};
//主函数中:Complext1(1,2);Complext2(2,3);Complext3;t3=t1+t2;
此时t1和t2的类型不定,就得对+进行运算符的重载;使其更符合人文化,其本质不变,t1.operator+(t2);
对象的类型不定,编译器不知道怎么输出,自己就得对<<和>>运算符进行重载,以达到输出对象的目的。还必须是友元函数;
classComplex;//这是第一步,类外声明。ostream&operator<<(ostream&out,constComplex&c);istream&operator>>(istream&in,Complex&c);classComplex{//这是第二步,对其在类内说明是朋友。friendostream&operator<<(ostream&out,constComplex&c);friendistream&operator>>(istream&in,Complex&c);};ostream&operator<<(ostream&out,constComplex&c){out<<"("<<c.m_real<<","<<c.m_imag<<")";returnout;//这是第三步,在类外进行定义。}istream&operator>>(istream&in,Complex&c){in>>c.m_real>>c.m_imag;returnin;}
关于这个<<对应一个要输出的值,在定义时,不用endl,回车。
对于Complate类的补充,t1 = t2 + 10; //成员方法重载即可。内部有一个隐藏参数
t1 = 10 + t2; //没有对象驱动,还要10.operator+(t2);是错的,所以此时用友元函数,传两个参数就是有两个参数。
运算符的重载要注意:
(1)、operator后面是一个合法的运算符,将右操作数做为函数的实参;
(2)、++ --前后的问题,用函数重载区分,后加的(int)参数;
(3)、?: . .* :: sizeof不能重载,其它的应该都可以进行重载;
例1:++i 和 i++有什么区别?
对其进行重载,如下:
#include<iostream>usingnamespacestd;classInt;ostream&operator<<(ostream&out,constInt&s);classInt{friendostream&operator<<(ostream&out,constInt&s);public:Int(intm=0):t(m){}~Int(){}public:Int&operator++()//++t先加1,再将此对象的引用返回{t++;return*this;}Intoperator++(int)//t++后加的要有一个参数int区分,{Inttmp(t);//创建一个临时对象,t++;//原有对象加了一下,returntmp;//返回临时对象,后加。}private:intt;};ostream&operator<<(ostream&out,constInt&s){out<<s.t;returnout;}intmain(void){Intt1(6);Intt2;Intt3;t2=++t1;cout<<"t1="<<t1<<",t2="<<t2<<endl;//对输出运算符重载了,才能输出对象。t3=t1++;cout<<"t1="<<t1<<",t3="<<t3<<endl;return0;}
运行结果如下:
从结果可以看出,确是实现了,这块的本质是运算符对++的重载。
前加,返回的是引用,后加还得调用构造函数和拷贝构造;所以前加++i;效率更高,运行速度也更快。
例2、String类
#include<iostream>#include<string.h>#include<assert.h>usingnamespacestd;classString;ostream&operator<<(ostream&out,constString&str);classString{friendostream&operator<<(ostream&out,constString&str);public:String(constchar*str=""){if(str==NULL){data=newchar[1];data[0]=0;}else{data=newchar[strlen(str)+1];strcpy(data,str);}}//String(constString&str){}String&operator=(constString&str){if(this!=&str){delete[]data;data=newchar[strlen(str.data)+1];strcpy(data,str.data);}return*this;}~String(){delete[]data;}public:Stringoperator+(constString&str){char*tmp;tmp=newchar[strlen(data)+strlen(str.data)+1];strcpy(tmp,data);strcat(tmp,str.data);returnString(tmp);}voidoperator+=(constString&str){char*new_data=newchar[strlen(data)+strlen(str.data)+1];strcpy(new_data,data);strcat(new_data,str.data);delete[]data;data=new_data;/*realloc(data,strlen(data)+strlen(str.data)+1);//此时对原有的数组空间进行动态扩长,//给谁扩长加上原先,一共要有多长即原有值不变。strcat(data,str.data);*/}charoperator[](intpos){assert(pos>=0&&pos<strlen(data));returndata[pos];}charoperator*(){returndata[0];}booloperator==(constString&str){returnstrcmp(data,str.data)?false:true;}booloperator!=(constString&str){return!(*this==str);//调用==这个编写过的函数}private:char*data;};ostream&operator<<(ostream&out,constString&str){out<<str.data;returnout;}intmain(void){Strings1("hello");Strings2("world");Strings3;s3=s1+s2;cout<<s3<<endl;s1+=s2;cout<<s1<<endl;cout<<s1[1]<<endl;cout<<*s1<<endl;if(s1==s3){cout<<"相等"<<endl;}else{cout<<"不相等"<<endl;}if(s1!=s3){cout<<"不相等"<<endl;}else{cout<<"相等"<<endl;}return0;}
对其+,+=,[],*,==,!=进行了运算符的重载,结果如下:
3、const和static
在C++中const是非常重要的,现在说明常函数之间的关系:普通函数可以调用常函数,常函数不能调用普通函数(因为没有this);
void fun()const{}
void fun(){} //一个有const,一个没有,参数类型不一样,所以这是函数的重载!
static在C++中有成员和方法,静态成员的在类外初始化;类的静态成员为所有对象所共享。
静态方法: (1)、可以调用该类的私有成员,(2)、应该位于类的作用域之中;(3)、类名直接调用,可以不用方法;
静态方法只能调用静态成员,和静态函数;非静态的可以调用静态成员或方法。
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。