运算符重载。
4.3
1、运算重载的概念和语法
所谓重载,就是赋予新的含义。函数重载(Function Overloading)可以让一个函数名有多重功能,在不同情况下进 行不同的操作。
格式:
返回值类型 operator 运算符名称 (形参表列){
//TODO:
}
complex operator+(const complex &A) const;
可以把operator+这一部分当作函数名,运算符重载其实就是定 义一个函数,在函数体内实现想要的功能,当用到该运算符时, 编译器会自动调用这个函数。也就是说,运算符重载是通过函数 实现的,它本质上是“函数重载”。
-----------这里解释了之前不理解的地方,为什么+号重新定义 了还能进行数值相加,原因是函数重载了,+号这个函数的名字 一样了,但是入口参数不一样,系统根据参数来判断什么功能。
2、C++运算符重载的规则
1、并不是所有的运算符都可以重载。能够重载的运算符包括:
+ - * / % ^ & | ~ ! = < > += -= *= /= %= ^= &= |= << >> <<= >>= == != <= >= && || ++ -- , ->* -> () [] new new[] delete delete[]
上述运算符中,[]是下标运算符,()是函数调用运算符。自增自减运算符的前置和后置形式都可以重载。
*****不能被重载的运算符:
长度运算符sizeof
条件运算符: ?
成员选择符.
对象选择符.*
域解析运算符::
2、重载不能改变运算符的优先级和结合性
3、重载不会改变运算符的用法,原有有几个操作数、操作数在 左边还是在右边,这些都不会改变。例如~号右边只有一个操 作数,+号总是出现在两个操作数之间,重载后也必须如此。
4、运算符重载函数不能有默认的参数,否则就改变了运算符操 作数的个数,这显然是错误的。
5、运算符重载函数既可以作为类的成员函数,也可以作为全局 函数,需要注意的是,作为全局函数时,可能需要友元函数 friend()的帮助来访问类中的私有成员。
complex complex:: operator+(const complex &A) const;
complex operator+(const complex &A,const complex &B);
****第一种是运算符重载函数作为类的成员函数时,它的参数少了一个,而且定义时候需要加上作用域::,少一个参数是因为这个参数是隐含的,就是本类中的this指针。
****第二种定义为全局运算符重载函数,就需要两个参数了。定义的时候也不要域名了。
6、箭头运算符->
下标运算符[]
函数调用运算符()
赋值运算符 =
*****它们只能以成员函数的形式重载
3、重载>>和<<(输入输出运算符)-------以全局函数实现
istream & operator>>(istream &in, complex &A)
{
in >> A.m_real >> A.m_imag;
return in;
}
****istream 表示输入流,cin 是 istream 类的对象,只不过这个对象是在标准库中定义的。之所以返回 istream 类对象的引用,是为了能够连续读取复数---------要申明为友元函数
ostream & operator<<(ostream &out, complex &A)
{
out << A.m_real <<" + "<< A.m_imag <<" i ";
return out;
}
cout<<A<<endl
***ostream 表示输出流,cout 是 ostream 类的对象。由于采用了引用的方式进行参数传递,并且也返回了对象的引用,所以重载后的运算符可以实现连续输出。-----为了能直接访问类中的私有成员变量,同样需要将该函数声明为类中的友元函数。
4、[]下标运算符重载*****只能以类的成员函数的形式进行重载
格式如下:
返回值类型 & operator[](参数) 或者
const 返回值类型 & operator[](参数)
使用第一种声明方式,运算符重载函数不仅可以访问对象,同时还可以修改对象。使用第二种声明方式,运算符重载函数只能访问而不能修改对象。
this指针是一个const指针,地址不能改,但能改变其指向的对象或者变量。
5、*****赋值运算符=
Book & Book::operator=(const Book &b)
{
if( this != &b)
{
this->m_price = b.m_price;
this->m_num = b.m_num;
//为bookmark赋值
int *bmTemp = new int[b.m_num];
for(int i=0; i<b.m_num; i++)
{
bmTemp[i] = b.m_bookmark[i];
}
this->m_bookmark = bmTemp;
}
return *this;
}
5、重载new和delete运算符
只有在需要自己管理内存时才会重载
void * className::operator new( size_t size )
{
//TODO:
}
以全局函数的形式重载 new 运算符:
void * operator new( size_t size ){
//TODO:
}
****两种重载形式的返回值相同,都是void *类型,并且都有一个参数,为size_t类型。在重载 new 或 new[] 时,无论是作为成员函数还是作为全局函数,它的第一个参数必须是 size_t 类型。size_t 表示的是要分配空间的大小,对于 new[] 的重载函数而言,size_t 则表示所需要分配的所有空间的总和。
同样的,delete 运算符也有两种重载形式。
以类的成员函数的形式进行重载:
void className::operator delete( void *ptr)
{
//TODO:
}
以全局函数的形式进行重载:
void operator delete( void *ptr){
//TODO:
}
****两种重载形式的返回值都是 void 类型,并且都必须有一个 void 类型的指针作为参数,该指针指向需要释放的内存空间。
4.3
1、运算重载的概念和语法
所谓重载,就是赋予新的含义。函数重载(Function Overloading)可以让一个函数名有多重功能,在不同情况下进 行不同的操作。
格式:
返回值类型 operator 运算符名称 (形参表列){
//TODO:
}
complex operator+(const complex &A) const;
可以把operator+这一部分当作函数名,运算符重载其实就是定 义一个函数,在函数体内实现想要的功能,当用到该运算符时, 编译器会自动调用这个函数。也就是说,运算符重载是通过函数 实现的,它本质上是“函数重载”。
-----------这里解释了之前不理解的地方,为什么+号重新定义 了还能进行数值相加,原因是函数重载了,+号这个函数的名字 一样了,但是入口参数不一样,系统根据参数来判断什么功能。
2、C++运算符重载的规则
1、并不是所有的运算符都可以重载。能够重载的运算符包括:
+ - * / % ^ & | ~ ! = < > += -= *= /= %= ^= &= |= << >> <<= >>= == != <= >= && || ++ -- , ->* -> () [] new new[] delete delete[]
上述运算符中,[]是下标运算符,()是函数调用运算符。自增自减运算符的前置和后置形式都可以重载。
*****不能被重载的运算符:
长度运算符sizeof
条件运算符: ?
成员选择符.
对象选择符.*
域解析运算符::
2、重载不能改变运算符的优先级和结合性
3、重载不会改变运算符的用法,原有有几个操作数、操作数在 左边还是在右边,这些都不会改变。例如~号右边只有一个操 作数,+号总是出现在两个操作数之间,重载后也必须如此。
4、运算符重载函数不能有默认的参数,否则就改变了运算符操 作数的个数,这显然是错误的。
5、运算符重载函数既可以作为类的成员函数,也可以作为全局 函数,需要注意的是,作为全局函数时,可能需要友元函数 friend()的帮助来访问类中的私有成员。
complex complex:: operator+(const complex &A) const;
complex operator+(const complex &A,const complex &B);
****第一种是运算符重载函数作为类的成员函数时,它的参数少了一个,而且定义时候需要加上作用域::,少一个参数是因为这个参数是隐含的,就是本类中的this指针。
****第二种定义为全局运算符重载函数,就需要两个参数了。定义的时候也不要域名了。
6、箭头运算符->
下标运算符[]
函数调用运算符()
赋值运算符 =
*****它们只能以成员函数的形式重载
3、重载>>和<<(输入输出运算符)-------以全局函数实现
istream & operator>>(istream &in, complex &A)
{
in >> A.m_real >> A.m_imag;
return in;
}
****istream 表示输入流,cin 是 istream 类的对象,只不过这个对象是在标准库中定义的。之所以返回 istream 类对象的引用,是为了能够连续读取复数---------要申明为友元函数
ostream & operator<<(ostream &out, complex &A)
{
out << A.m_real <<" + "<< A.m_imag <<" i ";
return out;
}
cout<<A<<endl
***ostream 表示输出流,cout 是 ostream 类的对象。由于采用了引用的方式进行参数传递,并且也返回了对象的引用,所以重载后的运算符可以实现连续输出。-----为了能直接访问类中的私有成员变量,同样需要将该函数声明为类中的友元函数。
4、[]下标运算符重载*****只能以类的成员函数的形式进行重载
格式如下:
返回值类型 & operator[](参数) 或者
const 返回值类型 & operator[](参数)
使用第一种声明方式,运算符重载函数不仅可以访问对象,同时还可以修改对象。使用第二种声明方式,运算符重载函数只能访问而不能修改对象。
this指针是一个const指针,地址不能改,但能改变其指向的对象或者变量。
5、*****赋值运算符=
Book & Book::operator=(const Book &b)
{
if( this != &b)
{
this->m_price = b.m_price;
this->m_num = b.m_num;
//为bookmark赋值
int *bmTemp = new int[b.m_num];
for(int i=0; i<b.m_num; i++)
{
bmTemp[i] = b.m_bookmark[i];
}
this->m_bookmark = bmTemp;
}
return *this;
}
5、重载new和delete运算符
只有在需要自己管理内存时才会重载
void * className::operator new( size_t size )
{
//TODO:
}
以全局函数的形式重载 new 运算符:
void * operator new( size_t size ){
//TODO:
}
****两种重载形式的返回值相同,都是void *类型,并且都有一个参数,为size_t类型。在重载 new 或 new[] 时,无论是作为成员函数还是作为全局函数,它的第一个参数必须是 size_t 类型。size_t 表示的是要分配空间的大小,对于 new[] 的重载函数而言,size_t 则表示所需要分配的所有空间的总和。
同样的,delete 运算符也有两种重载形式。
以类的成员函数的形式进行重载:
void className::operator delete( void *ptr)
{
//TODO:
}
以全局函数的形式进行重载:
void operator delete( void *ptr){
//TODO:
}
****两种重载形式的返回值都是 void 类型,并且都必须有一个 void 类型的指针作为参数,该指针指向需要释放的内存空间。