一、基本概念
(一) 函數重載的含義
所謂重載,就是重新賦予新的含義。函數重載就是對一個已有的函數賦予新的含義,使之實作新功能,是以,一個函數名就可以用來代表不同功能的函數,也就是”一名多用”。
(二) 為什麼要進行函數重載
一般情況下,編譯器對現有操作符的操作數是有一定的限制,但是通常情況下使用者使用class會自定義類型,而編譯器是不認可這種類型的操作符運算的,是以可以将操作符進行重載達到可以根據自定義類型進行運算;
(三)函數重載的一般格式
傳回值類型 operator op(參數)
(四)一般符号重載的實作步驟:
一般情況下函數重載使用成員函數實作
- 1)要承認操作符重載是一個函數,寫出函數名稱operator op ()
- 2)根據所要重載的操作符的操作數,寫出函數參數
- 3)根據函數的目的,完善函數傳回值(看函數是傳回引用 還是指針 元素)
- 4)實作具體的函數内容
二、具體的程式示例
程式分為三部分:
聲明:
MyString.h
具體實作:
MyString.cpp
應用:
example.cpp
運作平台為:windows 10 & VS2017,所有程式運作結果均正确
1.MyString.h
#pragma once
#include "iostream"
using namespace std;
class MyString
{
public:
//這是構造函數和析構函數
MyString();
MyString(const char *p);
MyString(const MyString &s);
~MyString();
private:
int m_len;
char* m_p;
public:
//實作 = 操作符的重載
MyString& operator=(const char *p);
MyString& operator= (const MyString &s);
//實作 [] 操作符的重載
char& operator[](int index);
//實作 << 操作符的重載
friend ostream & operator<<(ostream &out, MyString &s);
//實作 == 和 != 操作符的重載
bool operator==(const char *p);
bool operator!=(const char *p);
bool operator==(const MyString&s);
bool operator!=(const MyString &s);
//實作 < 操作符的重載
int operator<(const char *p);
int operator<(const MyString &s);
};
2.MyString.cpp
#include "MyString.h"
#include"math.h"
#include "iostream"
#pragma warning(disable:4996)
//構造函數:
//将對象初始化為空字元串
MyString::MyString()
{
m_len = 0;
m_p = new char[m_len + 1];
//開辟一個存放字元數組的空間,大小為(m_len + 1) *1 ,并且傳回首位址指派給指針變量m_p
strcpy(m_p, " ");
}
//将對象初始化為一個字元串
MyString::MyString(const char *p)
{
if (p == NULL)
{
m_len = 0;
m_p = new char[m_len + 1];
strcpy(m_p, "");
}else
{
m_len = strlen(p);
m_p = new char[m_len + 1];
strcpy(m_p, p);
}
}
//拷貝構造函數
//實作MyString s3 = s2;
MyString::MyString(const MyString &s)
{
m_len = s.m_len;
m_p = new char[m_len + 1]; //配置設定空間
strcpy(m_p, s.m_p);
}
//析構函數的實作
MyString::~MyString()
{
if (m_p != NULL)
{
delete[] m_p;
m_p = NULL;
m_len = 0;
}
}
//下面進行的是操作符重載
//等号 = 操作符重載
//用于實作s4 = "s2222"
MyString&MyString:: operator=(const char *p)
{
//因為s4已經配置設定記憶體,應該先将舊的記憶體空間删掉然後再配置設定新的
//1.釋放舊記憶體
if (m_p != NULL)
{
delete[] m_p;
m_p = NULL;
m_len = 0;
}else
{
//配置設定新的記憶體
if (p == NULL)
{
m_len = 0;
m_p = new char[m_len + 1];
strcpy(m_p, "");
}
else
{
m_len = strlen(p);
m_p = new char[m_len + 1];
strcpy(m_p, p);
}
return *this;
}
}
//用于實作s4 = s2
MyString&MyString:: operator= (const MyString &s)
{
if (m_p != NULL)
{
delete[] m_p;
m_p = NULL;
m_len = 0;
}else
{
//根據s(對應于s2)配置設定新的記憶體
m_len = s.m_len;
m_p = new char[m_len + 1];
strcpy(m_p, s.m_p);
return *this;
}
}
//實作[] 操作符重載
char&MyString::operator[](int index)
{
return m_p[index];
}
//注意這個是全局函數,是以函數名前面不能加上MyString::
ostream& operator<<(ostream &out, MyString &s)
{
cout << s.m_p;
return out;
}
//下面是實作==和!= 的重載,其中分為類和字元串的比較與類和類的比較
bool MyString::operator==(const char *p)
{
if (p == NULL)
{
if (m_len == 0)
{
return true;
}
else
{
return false;
}
}
else
{
if (m_len == strlen(p))
{
return !strcmp(m_p, p);
}
else
{
return false;
}
}
return true;
}
bool MyString::operator!=(const char *p)
{
return !(*this == p);
}
//兩個類之間的比較
bool MyString::operator==(const MyString&s)
{
if (m_len != s.m_len)
{
return false;
}
return !strcmp(m_p, s.m_p);
}
bool MyString::operator!=(const MyString &s)
{
return !(*this == s);
}
//實作 < 的重載
int MyString::operator<(const char *p)
{
return strcmp(this->m_p, p);
}
int MyString::operator<(const MyString &s)
{
return strcmp(this->m_p, s.m_p);
}
3.example.cpp
// 實作一個字元串類
//C語言中 沒有字元串這種類型,是通過數組來模拟字元串
//C++中 我們來設計一個字元串類 以零結尾的字元串
//若len為0,表示空串
#include "iostream"
#include "MyString.h"
using namespace std;
#pragma warning (disable: 4996)
int main()
{
MyString s1;
MyString s2("s2");
MyString s2_2 = NULL;
MyString s3 = s2;
//下面進行操作符重載
//=操作符
//兩種調用方式;
MyString s4 = "adfdfdn";
s4 = "s2222";
//調用方式二;
s4 = s2;
//實作[]重載
//當[]當右值的時候
s4[1] = 'a';
cout << "s4[1] = " << s4[1] << endl;
//實作<<操作符的重載
cout << s4 << endl; //相當于實作字元串的整體輸出
//實作== 和!= 的重載
MyString s5 = "ahhhh";
if (s5 == "shhsk")
{
cout << "true" << endl;
}
else
{
cout << "false" << endl;
}
if (s5 != "sjfddsj")
{
cout << "false" << endl;
}
else
{
cout << "true" << endl;
}
//兩個類之間做判斷
if (s5 == s2)
{
cout << "true" << endl;
}
else
{
cout << "false" << endl;
}
if (s5 != s2)
{
cout << "false" << endl;
}
else
{
cout << "true" << endl;
}
//實作大于小于号的符号重載
MyString s6 = "skdjfkld";
if (s6 < "kdjfkdj")
{
cout << "s6 smaller than skdjfkld" << endl;
}
else
{
cout << "s6 bigger than skdjfkld" << endl;
}
if (s6 < s5)
{
cout << "s6 smaller than s5" << endl;
}
else
{
cout << "s6 bigger than s5" << endl;
}
//使用類中的private:的指針
MyString s7 = "jdkfjdklfjdl";
strcpy(s7.c_str(), "lskjdfkljdklf");
cout << s7 << endl;
}