运算符重载
重载 +
成员函数实现+重载
#include <iostream>
using namespace std;
class Person {
public:
Person() {};
Person(int i) :age(i) {};
Person operator+(const Person&p) {
Person temp;
temp.age = this->age + p.age;
return temp;
}
private:
int age;
};
int main() {
Person p1(5), p2(10);
Person p3;
p3=p1 + p2;
return 0;
}
全局函数实现 + 重载
#include <iostream>
using namespace std;
class Person {
public:
Person() {};
Person(int i) :age(i) {};
int age;
};
Person operator+(const Person&p1,const Person&p2) {
Person temp;
temp.age = p1.age + p2.age;
return temp;
}
int main() {
Person p1(5), p2(10);
Person p3;
p3=p1 + p2;
return 0;
}
重载 <<
<<重载不可以写成成员函数,因为调用成员函数,需要如下那么使用,不符合常规。
全局函数重载 <<
#include <iostream>
using namespace std;
class Person {
public:
Person() {};
Person(int i) :age(i) {};
private:
int age;
friend ostream& operator<<(ostream&cout, Person &p1);
};
ostream& operator<<(ostream&cout, Person &p1) {
cout << p1.age ;
}
int main() {
Person p1(5);
cout << p1 <<endl;
return 0;
}
++i 和 i++的重载
后置的时候用占位参数来区分前置和后置
void operator++() {
}
//后置的时候用占位参数来区分前置和后置
void operator++(int) {
}
前置++部分完成
#include <iostream>
using namespace std;
class MyInt {
public:
MyInt(int i=0):num(i) {}
MyInt& operator++() {
this->num++;
return *this;
}
//后置的时候用占位参数来区分前置和后置
void operator++(int) {
}
int num;
};
ostream& operator<<(ostream& cout, MyInt &myInt) {
cout << myInt.num;
return cout;
}
int main() {
MyInt myInt;
cout << ++myInt << endl;
//myInt++;
return 0;
}
完整版
上面的版本的重载<<有一点问题,
需要把第二个参数前面加个const,目测是高版本的g++提升了安全性,视频里面不加const也能通过,但是我就是过不去,在visual studio里面也不报什么有价值的错,还是用g++发现了需要改进的问题。
#include <iostream>
using namespace std;
class MyInt {
public:
MyInt(int i=0):num(i) {}
MyInt& operator++() {
this->num++;
return *this;
}
//后置的时候用占位参数来区分前置和后置
MyInt operator++(int) {
//先保存目前的数据
MyInt temp = *this;
this->num++;
return temp;
}
int num;
};
ostream& operator<<(ostream& cout, const MyInt &myInt) {
cout << myInt.num;
return cout;
}
int main() {
MyInt myInt;
cout << ++myInt << endl;
cout << myInt++<<endl;
cout << myInt << endl;
return 0;
}
为什么一个返回值,一个返回引用?
对于一个int变量
int a = 10;
cout << ++(++a) << endl;
返回的结果是12,如果两个都是返回值,则
MyInt myInt;
cout << ++(++myInt) << endl;
的运行结果是2(初始值是0),但是
cout << myInt << endl;
的值是1.因为第一次++myInt,我们得到的是一个临时变量,因此,第二次的++操作是对这个临时变量进行的操作,并没有改变myInt的值。因此,前置++的返回值是一个引用。
指针运算符重载(智能指针)
智能指针——用来托管自定义类型对象,让在堆上创建的自定义对象可以自动释放
通过写一个智能指针类,通过智能指针类来创建自定义类的对象。在栈上创建智能指针对象,这样,智能指针对象被释放的时候,就把利用智能指针在堆上创建的自定义对象给一并析构了。
为了让智能指针和指向自定义类类型指针的功能一样,需要重载->和*.
智能指针类的例子如下:
//智能指针
//用来托管自定义类型的对象,让对象进行自动的释放
class smartPointer{
public:
smartPointer(Person * person){
this->person = person;
}
//重载->让智能指针对象 像Person *p一样去使用
Person * operator->(){
return this->person;
}
//重载 *
Person& operator*(){
return *this->person;
}
~smartPointer(){
cout << "智能指针析构了" << endl;
//析构通过智能指针在堆上创建的自定义类的对象
if (this->person !=NULL){
delete this->person;
this->person = NULL;
}
}
private:
//自动以类 Person
Person * person;
};
整体实现代码
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
class Person{
public:
Person(int age){
this->m_Age = age;
}
void showAge(){
cout << "年龄为:" << this->m_Age << endl;
}
~Person(){
cout << "Person的析构调用" << endl;
}
int m_Age;
};
//智能指针
//用来托管自定义类型的对象,让对象进行自动的释放
class smartPointer{
public:
smartPointer(Person * person){
this->person = person;
}
//重载->让智能指针对象 想Person *p一样去使用
Person * operator->(){
return this->person;
}
//重载 *
Person& operator*(){
return *this->person;
}
~smartPointer(){
cout << "智能指针析构了" << endl;
if (this->person !=NULL){
delete this->person;
this->person = NULL;
}
}
private:
Person * person;
};
void test01(){
//sp开辟到了栈上,自动释放,sp就是智能指针了
smartPointer sp(new Person(10));
// sp->->showAge(); 编译器优化了 写法
sp->showAge();
(*sp).showAge();
}
int main(){
test01();
system("pause");
return EXIT_SUCCESS;
}
赋值运算符重载(拷贝赋值函数)
系统自动生成的拷贝赋值函数是浅拷贝。下面代码就是一个深拷贝的例子(写的不够严谨)
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
//一个类默认创建 默认构造、析构、拷贝构造 operator=赋值运算符 进行简单的值传递
class Person{
public:
Person(int a){
this->m_A = a;
}
int m_A;
};
void test01()
{
Person p1(10);
Person p2(0);
p2 = p1; //赋值
cout << "p2 的m_A" << p2.m_A <<endl;
}
class Person2{
public:
Person2(char * name){
this->pName = new char[strlen(name) + 1];
strcpy(this->pName, name);
}
//重载 = 赋值运算符
Person2& operator= ( const Person2 & p){
//判断如果原来已经堆区有内容,先释放
if (this->pName != NULL){
delete[] this->pName;
this->pName = NULL;
}
this->pName = new char[strlen(p.pName) + 1];
strcpy(this->pName, p.pName);
return *this;
}
~Person2(){
if (this->pName != NULL){
delete[] this->pName;
this->pName = NULL;
}
}
char * pName;
};
void test02(){
Person2 p1("狗蛋");
Person2 p2("狗剩");
Person2 p3("");
p3 = p2 = p1;
cout << p2.pName << endl;
cout << p3.pName << endl;
}
int main(){
test01();
test02();
system("pause");
return EXIT_SUCCESS;
}
重载==和!=
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include <string>
using namespace std;
// ==
class Person{
public:
Person(string name, int age){
this->m_Name = name;
this->m_Age = age;
}
bool operator==( Person & p){
if (this->m_Name == p.m_Name && this->m_Age == p.m_Age){
return true;
}
return false;
}
bool operator!=( Person & p){
if (this->m_Name == p.m_Name && this->m_Age == p.m_Age){
return false;
}
return true;
}
public:
string m_Name;
int m_Age;
};
void test01()
{
Person p1("小明", 10);
Person p2("小强", 15);
Person p3("小强", 15);
if ( p1 == p2){
cout << "p1 和 p2 相等" << endl;
}else{
cout << "p1 和 p2 不相等" << endl;
}
if (p2 == p3){
cout << "p2 和 p3 相等" << endl;
}else{
cout << "p2 和 p3 不相等" << endl;
}
if (p1 != p2){
cout << "p1 和 p2 不相等" << endl;
}else{
cout << "p1 和 p2 相等" << endl;
}
}
int main(){
test01();
system("pause");
return EXIT_SUCCESS;
}
重载()
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include <string>
using namespace std;
// ()重载
class MyPrint{
public:
void operator()( string text)
cout << text << endl;
}
};
void test01(){
MyPrint myPrint;
myPrint("hello world1111"); // 仿函数
}
class MyAdd{
public:
int operator()(int v1,int v2){
return v1 + v2;
}
};
void test02(){
MyAdd myAdd;
cout << myAdd(1, 1) << endl;
cout << MyAdd()(1, 1) << endl; //匿名对象
}
int main(){
test01();
test02();
system("pause");
return EXIT_SUCCESS;
}
自定义字符串类型
MyString.h
#pragma once
#ifndef _CRT_SECURE_NO_WARNINGS
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
class MyString{
public:
MyString(const char * str);
MyString(const MyString & str);
~MyString();
//重载=运算符
MyString& operator = (const char * str);
MyString& operator=(const MyString & str);
//重载[]运算符
char& operator[](int index);
//重载 +运算符
MyString operator+(const char * str);
MyString operator+(const MyString& str);
//重载 == 运算符
bool operator==(const char * str);
bool operator==(const MyString & str);
private:
char * pString; //执行堆区的指针
int m_Size; // 字符串大小
friend ostream& operator<< (ostream& cout, const MyString & str);
friend istream& operator>> (istream& cin, const MyString & str);
};
#endif
MyString.cpp
#include "MyString.h"
ostream& operator<< (ostream& cout, const MyString & str){
cout << str.pString;
return cout;
}
//右移运算符重载
istream& operator>> (istream& cin, const MyString & str){
//先判断 原始是否有内容,如果有 清空
if (str.pString != NULL){
delete [] str.pString;
str.pString = NULL;
}
//让用户输入内容
char buf[1024];
cin >> buf;
//把用户输入的字符串 赋值给 str
str.pString = new char[strlen(buf) + 1];
strcpy(str.pString, buf);
str.m_Size = strlen(buf);
return cin;
}
MyString::MyString(const char * str){
cout << "有参构造调用" << endl;
this->pString = new char[strlen(str) + 1];
strcpy(this->pString, str);
this->m_Size = strlen(str);
}
MyString::MyString(const MyString & str){
this->pString = new char[strlen(str.pString) + 1];
strcpy(this->pString, str.pString);
this->m_Size = str.m_Size;
}
MyString::~MyString(){
cout << "析构函数调用" << endl;
if (this->pString != NULL){
delete[] this->pString;
this->pString = NULL;
}
}
char& MyString::operator[](int index){
return this->pString[index];
}
MyString& MyString::operator=(const char * str){
if (this->pString!=NULL){
delete[] this->pString;
this->pString = NULL;
}
this->pString = new char[strlen(str) + 1];
strcpy(this->pString, str);
return *this;
}
MyString& MyString::operator=(const MyString & str){
if (this->pString != NULL){
delete[] this->pString;
this->pString = NULL;
}
this->pString = new char[strlen(str.pString) + 1];
strcpy(this->pString, str.pString);
return *this;
}
MyString MyString::operator+(const char * str){
//计算返回的字符串开辟的大小
int newSize = this->m_Size + strlen(str) + 1;
char * tmp = new char[newSize];
memset(tmp, 0, newSize);
//拼接字符串
strcat(tmp, this->pString);
strcat(tmp, str);
MyString newStr(tmp);
delete[] tmp;
return newStr;
}
MyString MyString::operator+(const MyString& str){
int newSize = this->m_Size + strlen(str.pString) + 1;
char * tmp = new char[newSize];
memset(tmp, 0, newSize);
//拼接字符串
strcat(tmp, this->pString);
strcat(tmp, str.pString);
MyString newStr(tmp);
delete[] tmp;
return newStr;
}
bool MyString::operator==(const char * str){
if ( strcmp( this->pString , str) == 0
&& this->m_Size == strlen(str) ){
return true;
}
return false;
}
bool MyString::operator==(const MyString & str){
if (strcmp(this->pString, str.pString) == 0
&& this->m_Size == strlen(str.pString)){
return true;
}
return false;
}
main.cpp
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include "MyString.h"
using namespace std;
//测试 MyString
void test01(){
MyString str = "abc";
cout << str << endl;
cout << "请输入str新的内容:" << endl;
cin >> str;
cout << "新内容为:" << str << endl;
MyString str2(str);
MyString str3 = "aaaaaa";
str3 = str2;
str3 = "aaaa";
cout << "str3 = " << str3 << endl;
str3[0] = 'w';
cout << "str3 第一个位置为 = " << str3[0] << endl;
MyString str4 = "";
str4 = str2 + str3; //字符串拼接
cout << "str4 为 " << str4 << endl;
if (str3 == str4){
cout << "str3 与 str4相等" << endl;
}else{
cout << "str3 与 str4不相等" << endl;
}
}
int main(){
test01();
system("pause");
return EXIT_SUCCESS;
}