1. 程式人生 > >C++筆記(十九)——運算子過載函式

C++筆記(十九)——運算子過載函式

一、作用:

  • 使複雜函式的理解更直觀,程式更加簡單易懂

二、運算子過載函式的形式是:

返回型別 operator 運算子符號(引數說明)
{
  //函式體的內部實現
}

void operator +(Test&, Text&)
{
  //函式體的內部實現
}
  • 至少有一個引數是自定義型別(陣列,類)
  • 如果是單目運算子,只傳一個引數
  • 如果是雙目運算子,傳兩個引數

* 三、C++也規定了一些運算子不能夠自定義過載

  • 例如: “::”、“*”、“.”、“?:”。 即作用域、取值、取成員、三目運算子

四、常見運算子過載函式的使用

注:C++會隱藏第一個引數,轉而取代的是一個this指標

4.1 一種是作為類的友元函式進行使用

如:

friend void operator + (Test&, Test&);

具體例子:

.h標頭檔案

#ifndef __OPERATOR_OVERWRITE_H__
#define __OPERATOR_OVERWRITE_H__

class MyString
{
private:
	char *m_str;
public:
	MyString(char *m_str);
	~MyString();
	void print();
	//friend void add(MyString &ob1, MyString &ob2);
	friend void operator + (MyString &ob1, MyString &ob2);
};
extern void operator + (MyString &ob1, MyString &ob2);
//extern void add(MyString &ob1, MyString &ob2);
#endif

operator_overwrite.cpp檔案

#include "operator_overwrite.h"
#include <iostream>
#include <string>

using namespace std;

MyString::MyString(char *str)
{
	m_str = new char[strlen(str) + 1];
	strcpy(m_str, str);
	cout << "建構函式" << endl;
}

MyString::~MyString()
{
	delete [] m_str;
	cout << "析構MyString" << endl;
}

void MyString::print()
{
	cout << "m_str = " << m_str << endl;
}

void operator + (MyString &ob1, MyString &ob2)
//void add(MyString &ob1, MyString &ob2)
{
	char *p = new char[strlen(ob1.m_str) + 1];
	strcpy(p, ob1.m_str);
	delete[] ob1.m_str; //釋放舊的儲存空間
	ob1.m_str = p;
	strcat(ob1.m_str, ob2.m_str);
}

main.cpp檔案

#include "operator_overwrite.h"
#include <iostream>

using namespace std;

int main()
{
	MyString str1((char *)"hehe");
	MyString str2((char *)"haha");

	str1.print();
	str2.print();

	//第一種表示方法:add(str1, str2);
        //第二種表示方法:operator + (str1, str2); //運算子過載的原型
        //第三種表示方法:
        str1 + str2;

	str1.print();
	getchar();
	return 0;
}

4.2 一種則是作為類的成員函式進行使用

避免了重新定義額外的函式,如:

Temp operator + (Temp &t)
{
   ...;
}

具體例子:

operator_overwrite1.h檔案

#ifndef __OPERATOR_OVERWRITE1_H__
#define __OPERATOR_OVERWRITE1_H__

class MyString
{
private:
	char *m_str;
public:
	MyString(char *str);
	~MyString();
	void print();

	void operator + (MyString &ob);//運算子過載函式
};

#endif

operator_overwrite1.cpp檔案

#include "operator_overwrite1.h"
#include <iostream>

using namespace std;

MyString::MyString(char *str)
{
	cout << "建構函式" << endl;
	m_str = new char[strlen(str) + 1];
	strcpy(m_str, str);
}

MyString::~MyString()
{
	cout << "解構函式" << endl;
	delete[] m_str;
}

void MyString::print()
{
	cout << "m_str = " << m_str << endl;
}

void MyString::operator + (MyString &ob)
{
	char *p = new char[strlen(this->m_str) + strlen(ob.m_str) + 1];
	strcpy(p, this->m_str);
	delete[] this->m_str;//釋放this->str指向的舊空間
	this->m_str = p;
	strcat(this->m_str, ob.m_str);
}

main.cpp檔案

#include "operator_overwrite1.h"
#include <iostream>

using namespace std;

int main()
{
	{
		MyString aa("你好");
		MyString bb("明天!");

		aa.print();
		bb.print();

		//aa.operator+(bb);//運算子過載原型
		aa + bb;
		aa.print();
	}
	
	getchar();
	return 0;
}

注:

  • 問題1、如果再定義一個新物件cc,將bb的值直接賦給cc(舊物件賦值給新物件),即

MyString cc = bb;

則需要再新增一個拷貝建構函式

MyString(const MyString &ob)
{
      cout << "拷貝建構函式" << endl;
      str = new char[strlen(ob.str)+1];
      strcpy(str, ob.str);
}
  • 問題2、舊物件給舊物件賦值時

解決辦法:可通過等號運算子過載

void MyString::operator = (MyString &ob)
{
	delete[] m_str;//釋放this->str指向的舊空間
        m_str = new char[strlen(m_str) + 1];
	strcpy(m_str, ob.m_str);
        cout << "=過載" << endl;
}


在main函式中加上過載原型:
MyString dd;
//dd.operator = (cc); //操作原型
dd = cc;
dd.print();