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指针,因此这两个函数的参数列表不同。
- C++类中的六个默认函数(二)
- 类的六个默认成员函数(二)
- C++类中的六个默认函数(一)
- 类的六个默认成员函数总结(一)
- 类的六个默认成员函数(转)
- C++类的六个默认成员函数
- 类的六个默认成员函数
- c++类中六个默认成员函数
- 一个类的六个默认函数
- 类的六个默认成员函数
- 类的六个默认成员函数
- C++11 类的六个默认函数及其使用
- 类和六个默认函数及this指针
- 浅谈类的六个默认的成员函数
- 详解c++中类的六个默认的成员函数
- 类的六个默认函数及运算符的重载
- 详解c++中类的六个默认的成员函数
- 详解c++中类的六个默认的成员函数
- jQuery选择器之元素选择器
- 商品列表筛选排序规则可配置化管理
- ES6学习笔记
- AndroidAutoLayout
- SCI-Hub
- C++类中的六个默认函数(二)
- JDK中的Timer和TimerTask详解
- c++ 对象模型与内存结构
- 室内定位之蓝牙Beacon-部署方案
- path与classpath区别
- css三种样式表区别,优先级。
- java3的 DateUtils方法
- ACM程序设计题目 Problem N-14
- 管理