C++基础知识(Ⅴ)

前言

参考资料:http://c.biancheng.net/cplus/

一.运算符重载

运算符重载:定义一个函数,重载某个运算符。
运算符重载的格式:

返回值类型 operator 运算符名称(参数列表){};

能够重载的运算符如下:

可重载的运算符列表1可重载的运算符列表2
+, -, *, /, %, ^, ++, –|, &, ||, &&
!=, ==, <=, >=~, !, <<, >>, ->
=, +=, -=, *=, /=, %=, ^=(), []

注意,有四个运算符不能被重载。

不能重载的运算符
长度运算符sizeof
条件运算符:?
成员选择符.
域解析运算符::

运算符重载不会改变运算符的优先级和用法,且重载函数中不能有默认的参数。
绝大部分运算符可以重载为成员函数、友元函数和全局函数
1)一元运算符由于只有一个形参作为运算符的右操作数,一个this指针指向左操作数,因此一般重载为成员函数。
2)二元运算符需要定义两个形参,为了满足交换律、结合律等运算规则,通常重载为友元函数。

1.重载数学运算符

数学运算符分为四则运算符,关系运算符和自增自减运算符。
四则运算符有+,-,*,/,+=,-=,*=,/=其中+,-,*,/是二元运算符,以友元形式重载,+=,-=,*=,/=是一元运算符,使用成员函数重载。
关系运算符有>,<,>=,<=,==,!=。
自增自减运算符是++和–,是一元运算符,必须定义为成员函数重载。注意,需要区分前加和后加。
赋值运算符=只能重载为成员函数。

#include<iostream>
#include<string>
using namespace std;

class Real {
private:
	double m_real;
public:
	Real(double real = 0.0) :m_real(real) {};

	//二元运算符,使用友元形式重载
	friend Real operator+(const Real& r1, const Real& r2);
	friend Real operator-(const Real& r1, const Real& r2);
	friend Real operator*(const Real& r1, const Real& r2);
	friend Real operator/(const Real& r1, const Real& r2);
	
	friend bool operator==(const Real& r1, const Real& r2);
	friend bool operator!=(const Real& r1, const Real& r2);

	//一元运算符,使用成员函数形式重载
	Real& operator+=(const Real& r);
	Real& operator-=(const Real& r);
	Real& operator*=(const Real& r);
	Real& operator/=(const Real& r);
	Real& operator=(const Real& r);
	bool operator<(const Real& r);
	bool operator>(const Real& r);
	bool operator>=(const Real& r);
	bool operator<=(const Real& r);

	Real operator++(); //++i,前加
	Real operator++(int); //i++,后加

	//定义普通成员函数
	double real() {
		return m_real;
	}
};

//定义重载函数
Real operator+(const Real& r1, const Real& r2) {
	Real r;
	r.m_real = r1.m_real + r2.m_real;
	return r;
}

Real operator-(const Real& r1, const Real& r2) {
	Real r;
	r.m_real = r1.m_real - r2.m_real;
	return r;
}

Real operator*(const Real& r1, const Real& r2) {
	Real r;
	r.m_real = r1.m_real * r2.m_real;
	return r;
}

Real operator/(const Real& r1, const Real& r2) {
	Real r;
	r.m_real = r1.m_real / r2.m_real;
	return r;
}

bool operator==(const Real& r1, const Real& r2) {
	if (r1.m_real == r2.m_real) {
		return true;
	}
	else {
		return false;
	}
}

bool operator!=(const Real& r1, const Real& r2) {
	if (r1.m_real != r2.m_real) {
		return true;
	}
	else {
		return false;
	}
}

Real& Real::operator+=(const Real& r) {
	this->m_real += r.m_real;
	return *this;
}

Real& Real::operator-=(const Real& r) {
	this->m_real -= r.m_real;
	return *this;
}

Real& Real::operator*=(const Real& r) {
	this->m_real *= r.m_real;
	return *this;
}

Real& Real::operator/=(const Real& r) {
	this->m_real /= r.m_real;
	return *this;
}

Real& Real::operator=(const Real& r) {
	if (this != &r) {
		//判断是否给自己赋值
		this->m_real = r.m_real;
	}
	return *this;
}

bool Real::operator>(const Real& r) {
	if (this->m_real > r.m_real) {
		return true;
	}
	else {
		return false;
	}
}

bool Real::operator<(const Real& r) {
	if (this->m_real < r.m_real) {
		return true;
	}
	else {
		return false;
	}
}

bool Real::operator>=(const Real& r) {
	if (this->m_real >= r.m_real) {
		return true;
	}
	else {
		return false;
	}
}

bool Real::operator<=(const Real& r) {
	if (this->m_real <= r.m_real) {
		return true;
	}
	else {
		return false;
	}
}

Real Real::operator++() {
	++m_real;
	return *this;
}

Real Real::operator++(int) {
	Real temp = *this;
	m_real++;
	return temp;
}

int main() {
	Real r1(3);
	Real r2(5);
	
	Real r3 = r1 + r2;
	Real r4 = r1 - r2;
	Real r5 = r1 * r2;
	Real r6 = r1 / r2;
	cout << "r3=" << r3.real() << "\nr4=" << r4.real() << "\nr5=" << r5.real() << "\nr6=" << r6.real() << endl;
	r3 += r1;
	cout << "r3+r1=" << r3.real() << endl;
	r4 -= r1;
	cout << "r4-r1=" << r4.real() << endl;
	r5 *= r2;
	cout << "r5*r2=" << r5.real() << endl;
	r6 /= r2;
	cout << "r6/r2=" << r6.real() << endl;

	Real r7;
	r7 = r1;
	cout << "r7=" << r7.real() << endl;
	cout << "++r7=" << (++r7).real() << endl;
	r7 = r1;
	cout << "r7++=" << (r7++).real() << endl;

	cout << (r1 == r2) << '\n' << (r1 != r2) << endl;
	return 0;
}

2.重载输入输出运算符

输入输出运算符须重载为友元函数形式。
在相应的类中,对输入运算符>>的重载如下:

//在类中声明
friend istream& operator>>(istream& in, Real& r);

//在类外定义
istream& operator>>(istream& in, Real& r){
    in >> r.m_real;
    return in;
} 

int main(){
    Real r1;
    cin >> r1;
}

同理,对输出运算符<<进行重载如下:

//类中声明
friend ostream& operator<<(ostream& out, Real& r);

//类外定义
ostream& operator<<(ostream& out, Real& r){
    out << r.m_real << endl;
}

int main(){
    Real r1;
    cin >> r1;
    cout << r1 << endl;
}

3.重载下标运算符[]

下标运算符必须以成员函数的形式进行重载。
开发时常用两种形式:
1)返回值类型 & operator[] (参数);
2)const 返回值类型 & operator[] (参数) const;
重载[]可对对象进行下标运算。

class Array {
public:
	Array(int length = 0);
	~Array();

	int& operator[](int i);
	const int& operator[](int i) const;

private:
	int m_length;  //表示数组长度
	int* m_p;  //数组指针
};

Array::Array(int length): m_length(length){
    if(length == 0){
        m_p = NULL;
    }
    else{
        m_p = new int[length];
    }
}

Array::~Array(){
    delete[] m_p;
}
i
nt& Array::operator[](int i) {
	return m_p[i];
}

const int& Array::operator[](int i) const {
	return m_p[i];
}

4.重载类型强制转换运算符()

类型强制转换运算符()是一元运算符,只能重载为成员函数。

//在类内声明
operator int();

//在类外定义
Real::operator int() {
	return (int)m_real;
}

int main(){
	Real r8(2.554);
	cout << "float(r8)=" << (float)r8 << endl;
}

二.拷贝

1.拷贝构造函数

以拷贝的形式初始化一个对象,调用拷贝构造函数。
如果不自己定义拷贝构造函数,编译器会自动生成一个默认的拷贝构造函数。

class Array {
public:
	Array(int length = 0);
	Array(const Array& arr); //声明拷贝构造函数
	~Array();

	int& operator[](int i);
	const int& operator[](int i) const;

private:
	int m_length;  //表示数组长度
	int* m_p;  //数组指针
};

//定义拷贝构造函数,必须是const的引用
Array::Array(const Array& arr){
    this->m_length = arr.m_length;
    if(this->m_length == 0){
        this->m_p = NULL;
    }
    else{
        this->m_p = new int[length];
    }
}

int main(){
    Array arr1(10);
    Array arr2(arr1);  //调用拷贝构造函数
    Array arr3 = arr1;  //调用拷贝构造函数
    return 0;
}

2.深拷贝与浅拷贝

浅拷贝:浅拷贝只对对象中的数据成员进行简单赋值给新创建的对象,而对指针成员,直接将新对象的指针成员指向被拷贝对象的真正成员。

深拷贝:对于对象中动态成员,不是简单赋值,而需要重新动态分配空间。因此必须显式定义深拷贝构造函数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值