C++类中的六个默认函数(二)

来源:互联网 发布:东华 数据库 编辑:程序博客网 时间:2024/06/05 05:15

一、友元

友元函数:友元函数可以直接访问类的私有成员,它是定义在类外部的普通函数,不属于任何类,但需要在类的内部声明,声明时需要加friend关键字。

friend double FunctionName(参数列表 );class CPoint{friend class CTest;public:   CPoint(const double _dX = 0.0f, const double _dY =0.0f): m_dX( _dX), m_dY( _dY)   {}   friend double Distance( const CPoint _pt1, const CPoint _pt2);   //double Distance( const CPoint _pt1, const CPoint _pt2);private:   double m_dX;   double m_dY;};

1、友元函数说明:

a、友元函数可访问类的私有成员,但不是类的成员函数;

b、友元函数不能用const修饰;

c、友元函数可以在类定义的任何地方声明,不受类访问限定符限制;

d、一个函数可以是多个类的友元函数,但只需在各个类中分别声明;

e、友元函数的调用与普通函数的调用和原理相同;

f、其声明可以放在类的私有部分,也可以放在公有部分,无区别

2、友元类:友元类的所有成员函数都可以是另一个类的友元函数,都可以访问另一个类中的非公有成员(当希望一个类可以存取另一个类的私有成员时,可以将该类声明为另一个类的友元类)。

友元的优缺点:提高了程序的运行效率;但破坏了类的隐藏性和封装性。

注意:友元关系是单向的,不能继承,不具有交换性,且不能传递。

二、赋值操作符的重载

重载操作符是具有特殊函数名的函数,关键字operator后面接需要定义的操作符符号。操作符重载也是一个函数,具有返回值和形参表。它的形参数目与操作符的操作数目相同,函数调用操作符可以接受任意数目的操作数。使用运算符重载可以提高代码的可读性。

返回类型  operate  操作符 (参数列表)

不可以被重载的操作符有:

成员选择符(.)            成员对象选择符(.*)

域解析操作符(::)       条件操作符(?:)

(除了赋值号=之外,基类中被重载的操作符都将被派生类继承)

注意:

1、不能通过连接其他符号来创建新的操作符:比如operator@;void operator @(){}

2、重载操作符必须有一个类类型或者枚举类型的操作数

int operator +(const int _iNum1 , const int _iNum2 )// 报错

{

return ( _iNum1 + _iNum2);

}

typedef enum TEST {one ,two ,three };

int operator+(const int _iNum1 , const TEST _test )

{

return _iNum1;

}

3、用于内置类型的操作符,其含义不能改变,例如:内置的整型+,不能改变其含义

4、不再具备短求职特性重载操作符不能保证操作符的求值顺序,在重载&&和||中,对每个操作数都要进行求值,而且对操作数的求职顺序不能做规定,因此:重载&&、||和逗号操作符不是好的做法--重载后不能改变运算符的操作对象的个数以及其原有的优先级

5、作为类成员的重载函数,其形参看起来比操作数数目少1是因为成员函数的操作符有一个默认的形参this,限定为第一个形参。

CTest operator+(const CTest test1, const CTest test2)const // 报错

{

return test1;

}

CTest operator+(const CTest test1)const

{

return test1;

}

6、一般将算术操作符定义为非成员函数,将赋值运算符定义成员函数

7、操作符定义为非类的成员函数时,一般将其定义为类的友元

8、== 和 != 操作符一般要成对重载

9、下标操作符[]要重载两次:一个非const成员并返回引用,一个是const成员并返回引用

10、解引用操作符*和->操作符,不显示任何参数

11、自增自减操作符前置式++/--必须返回被增量或者减量的引用后缀式操作符必须返回旧值,并且应该是值返回而不是引用返回

12、输入操作符>>和输出操作符<<必须定义为类的友元函数(重载为类的成员函数不合理,调用时会与逻辑相反:a<<out;)

使用重载操作符,可以令程序更自然、更直观,而滥用操作符重载会使得类难以理解,在实践中很少发生明显的操作符重载滥用。但有些程序员会定义operator+来执行减法操作,当一个重载操作符不明确时,给操作符取一个名字更好,对于很少用的操作,使用命名函数通常比用操作符好,如果不是普通操作,没有必要为简洁而用操作符。

(编译器对于拷贝构造函数和赋值运算符在底层的实现相同)

例:实现一个复数类

//复数类class Complex{public:Complex(double real = 0.0,double image = 0.0)//构造函数:_real(real),_image(image){}Complex(const Complex& c)//拷贝构造函数:_real(c._real),_image(c._image){}Complex& operator=(const Complex c) //赋值运算符的重载{if(this != &c){_real = c._real;_image = c._image;}return *this;}Complex& operator*=(const Complex c)  //*=符号的重载{_real *= c._real;_image *= c._image;return *this;}Complex& operator/=(const Complex c)  // /=符号的重载{if(c._real != 0 && c._image != 0){_real /= c._real;_image /= c._image; }return *this;}Complex operator*(const Complex c)  //乘号的重载{return Complex(_real*c._real,_image*c._image);}Complex operator/(const Complex c)   //除号的重载{if(c._real != 0 && c._image != 0){return Complex(_real/c._real,_image/c._image);}else{return *this;}}Complex operator+(const Complex c)   //加号的重载{return Complex(_real+c._real,_image+c._image);}  Complex operator-(const Complex c)  //减号的重载{return Complex(_real-c._real,_image-c._image);}Complex& operator+=(const Complex c)   //+=重载{_real += c._real;_image += c._image;return *this;}Complex& operator-=(const Complex c)   //-=重载{_real -= c._real;_image -= c._image;return *this;}bool operator == (const Complex& c)  //==重载{        return (_real==c._real && _image==c._image);}bool operator != (const Complex& c)   //!=重载{        return (_real!=c._real || _image!=c._image);}//复数不能比较大小/*bool operator >=(const Complex& c){return (_real>=c._real && _image>=c._image);}bool operator >(const Complex& c){return (_real>c._real && _image>c._image);}bool operator <=(const Complex& c){return (_real<=c._real && _image<=c._image);}bool operator <(const Complex& c){return (_real<c._real && _image<c._image);}*/private:double _real;double _image;};int main(){Complex c1(1.0,2.0);Complex c2(0.0,4.0);Complex ret;ret = c1 - c2;ret = c1*c2;ret = c1/c2;system("pause");return 0;}

三、取地址操作符重载

四、const修饰的取地址操作符重载


关于const修饰类成员:

1、const修饰形参,一般和引用同时使用

2、const修饰返回值

3、const修饰类数据成员,必须在构造函数的初始化列表中初始化

4、const修饰类成员函数,实际修饰隐含的this,表示在类中不可以对类的任何成员进行修改

5、在const修饰的成员函数中要对类的某个数据成员进行修改,该数据成员定义声明是必须加mutable关键字

 const对象不可以调用非const成员函数。

const对象可以调用非const成员函数和const成员函数 。

const成员函数内可以调用其它的const成员函数。

非const成员函数内可以调用其它的const成员函数非const成员函数。


void FunTest()与void FunTest()const在类中构成函数重载,因为const修饰的是this指针,因此这两个函数的参数列表不同。





0 0
原创粉丝点击