C++前置++、后置++、不等号!及赋值运算符重载
2017-03-11 08:38
211 查看
运算符重载的主要目的是为了让类对象能像普通数据类型一样能够进行加减乘除,自加自减等操作,非常直观方便。现在来回顾C++的自加减(分前置与后置)以及不等号非运算符,赋值运算符的重载。
1 ++重载
(1)前置++运算符的重载方式:
成员函数的重载: 函数类型& operator++()
友元函数的重载:friend 函数类型& operator++(类类型& )
(2)后置++运算符的重载方式:
成员函数的重载:函数类型& operator++(int)
友元函数的重载:friend 函数类型& operator++(类类型&, int)
注意,为了区分前置++与后置++的区别,需要在参数后增加一个"int"以示区分。含有"int"的重载方式为后置++,否则为前置++。前置--与后置--类似用法。前面说过,成员函数与友元函数的重载如果同时存在时,会先调用成员函数的重载,但是在++或--时,成员函数与友元函数的重载是不能同时存在的。
下面举一个例子:
[cpp] view
plain copy
#ifndef _INTEGER_H_
#define _INTEGER_H_
class Integer
{
public:
Integer(int n);
~Integer();
void Display();
Integer& operator++(); //成员方式重载前置++
Integer& operator++(int); //成员方式重载后置++
friend Integer& operator++(Integer& i);//友元函数重载前置++
friend Integer& operator++(Integer& i, int);//友元函数重载后置++
private:
int n_;
};
#endif
下面是它们的具体代码实现:
[cpp] view
plain copy
#include "Integer.h"
Integer::Integer(int n):n_(n){}
Integer::~Integer(){}
void Integer::Display() const
{
cout << n_ << endl;
}
//最好优先使用成员函数重载,
//成员函数重载前置++
Integer& Integer::operator++()
{
++n_;
return *this;
}
//成员函数重载后置++
Integer& Integer::operator++(int)
{
Integer tmp(n_);
++n_;
return tmp;
}
//友元重载前置++
Integer& operator++(Integer& i)
{
++i.n_;
return i;
}
//友元重载后置++
Integer& operator++(Integer& i, int)
{
Integer tmp(i.n_);
++i.n_;
return tmp;
}
关于!及=赋值运算符的重载以String类进行说明:
下面是String类的定义:
[cpp] view
plain copy
#ifndef STRING_H_
#define STRING_H_
class String
{
public:
explicit String(const char *str="");
String(const String& other);
~String();
//应用于s="abc";的情况
String& operator=(const char *str);//重载=
bool operator!() const; //重载!
void Display() const;
private:
char* str_;
char* AllocAndCopy(const char* str);
};
#endif
下面是具体实现:
[cpp] view
plain copy
#include <string.h>
#include <iostream>
#include "String.h"
using namespace std;
String::String(const char *str)
{
str_ = AllocAndCopy(str);
}
String::~String()
{
delete [] str_;
}
char* String::AllocAndCopy(const char* str)
{
int len = strlen(str)+1;
char* newstr = new char[len];
memset(newstr, 0, len);
strcpy(newstr, str);
return newstr;
}
//深拷贝,copy assign
String& String::operator=(const String& other) //s1 = s2
{
if( this == &other)
return *this;
delete [] str_;
str_ = AllocAndCopy(other.str_);
return *this;
}
String& String::operator=(const char* str) //s1="abc"
{
delete [] str_;
str_ = AllocAndCopy(str);
return *this;
}
bool String::operator!() const
{
return (strlen(str_) != 0 )
}
void String::Display() const
{
cout << str_ << endl;
}
针对String类写的一个简单的用例:
[cpp] view
plain copy
#include "String.h"
#include <iostream>
using namespace std;
int main()
{
String s1("abc");
String s2(s1);//copy.
String s3;//带默认参数
s3 = s1; //调用赋值运算符
s3.Display();
//默认的处理方式为:将字符串构造成String类对象,再赋值至s3,如果在构造函数前加上explicit声明,则会发生编译错误。解决的方式需要重载一个参数为const char *的等号运算符即可
s3 = "xxx"; //调用参数为const char *的赋值运算符
String s4;
bool notempty;
notempty = !s4;
cout << notempty << endl; //1
s4 = "aaa";
notempty = !s4;
cout << notempty << endl; //0
return 0;
}
1 ++重载
(1)前置++运算符的重载方式:
成员函数的重载: 函数类型& operator++()
友元函数的重载:friend 函数类型& operator++(类类型& )
(2)后置++运算符的重载方式:
成员函数的重载:函数类型& operator++(int)
友元函数的重载:friend 函数类型& operator++(类类型&, int)
注意,为了区分前置++与后置++的区别,需要在参数后增加一个"int"以示区分。含有"int"的重载方式为后置++,否则为前置++。前置--与后置--类似用法。前面说过,成员函数与友元函数的重载如果同时存在时,会先调用成员函数的重载,但是在++或--时,成员函数与友元函数的重载是不能同时存在的。
下面举一个例子:
[cpp] view
plain copy
#ifndef _INTEGER_H_
#define _INTEGER_H_
class Integer
{
public:
Integer(int n);
~Integer();
void Display();
Integer& operator++(); //成员方式重载前置++
Integer& operator++(int); //成员方式重载后置++
friend Integer& operator++(Integer& i);//友元函数重载前置++
friend Integer& operator++(Integer& i, int);//友元函数重载后置++
private:
int n_;
};
#endif
下面是它们的具体代码实现:
[cpp] view
plain copy
#include "Integer.h"
Integer::Integer(int n):n_(n){}
Integer::~Integer(){}
void Integer::Display() const
{
cout << n_ << endl;
}
//最好优先使用成员函数重载,
//成员函数重载前置++
Integer& Integer::operator++()
{
++n_;
return *this;
}
//成员函数重载后置++
Integer& Integer::operator++(int)
{
Integer tmp(n_);
++n_;
return tmp;
}
//友元重载前置++
Integer& operator++(Integer& i)
{
++i.n_;
return i;
}
//友元重载后置++
Integer& operator++(Integer& i, int)
{
Integer tmp(i.n_);
++i.n_;
return tmp;
}
关于!及=赋值运算符的重载以String类进行说明:
下面是String类的定义:
[cpp] view
plain copy
#ifndef STRING_H_
#define STRING_H_
class String
{
public:
explicit String(const char *str="");
String(const String& other);
~String();
//应用于s="abc";的情况
String& operator=(const char *str);//重载=
bool operator!() const; //重载!
void Display() const;
private:
char* str_;
char* AllocAndCopy(const char* str);
};
#endif
下面是具体实现:
[cpp] view
plain copy
#include <string.h>
#include <iostream>
#include "String.h"
using namespace std;
String::String(const char *str)
{
str_ = AllocAndCopy(str);
}
String::~String()
{
delete [] str_;
}
char* String::AllocAndCopy(const char* str)
{
int len = strlen(str)+1;
char* newstr = new char[len];
memset(newstr, 0, len);
strcpy(newstr, str);
return newstr;
}
//深拷贝,copy assign
String& String::operator=(const String& other) //s1 = s2
{
if( this == &other)
return *this;
delete [] str_;
str_ = AllocAndCopy(other.str_);
return *this;
}
String& String::operator=(const char* str) //s1="abc"
{
delete [] str_;
str_ = AllocAndCopy(str);
return *this;
}
bool String::operator!() const
{
return (strlen(str_) != 0 )
}
void String::Display() const
{
cout << str_ << endl;
}
针对String类写的一个简单的用例:
[cpp] view
plain copy
#include "String.h"
#include <iostream>
using namespace std;
int main()
{
String s1("abc");
String s2(s1);//copy.
String s3;//带默认参数
s3 = s1; //调用赋值运算符
s3.Display();
//默认的处理方式为:将字符串构造成String类对象,再赋值至s3,如果在构造函数前加上explicit声明,则会发生编译错误。解决的方式需要重载一个参数为const char *的等号运算符即可
s3 = "xxx"; //调用参数为const char *的赋值运算符
String s4;
bool notempty;
notempty = !s4;
cout << notempty << endl; //1
s4 = "aaa";
notempty = !s4;
cout << notempty << endl; //0
return 0;
}
相关文章推荐
- C++回顾之前置++、后置++、不等号!及赋值运算符重载
- C++回顾之前置++、后置++、不等号!及赋值运算符重载
- 框架页面尽可以这么用(后置代码中控制框架)
- ORA-00927: 缺少等号
- 正则判断字符串(等号或单引号)
- C++赋值运算符重载
- .NET在后置代码中输入JS提示语句(背面不会变白)
- 关于两个等号与三个等号的应用
- jQuery对象与dom对象不能划等号
- AdRotator,广告轮播 #2 -- 以「后置程序代码(Code Behind)」与「数据库」来作设定
- 自定义style,在后置代码中引用已定义的样式的方式
- NET在后置代码中输入JS提示语句(背景不会变白)
- .NET在后置代码中输入JS提示语句(背景不会变白)
- 多一个等号,足以让你文件不断增大
- g723源码详细分析-19-基音后置滤波器
- JavaScript里面三个等号和两个等号的区别
- g729源码分析-10-后置滤波处理(一)
- php中拷贝构造函数、赋值运算符重载
- JavaScript 的三等号 "===" 以及 new String("")的实质
- 重载自增运算符(前置自增++p和后置自增p++)