还有类型转换函数
#include <iostream>
using namespace std;
class Complex{
// friend Complex complexAdd(Complex &c1, Complex &c2);
// friend Complex operator+(Complex &c1, Complex &c2);
// friend Complex& operator+= (Complex &c1, Complex &c2);
friend ostream& operator<<(ostream &os, Complex &c);
friend istream& operator>>(istream &is, Complex &c);
public:
Complex(){
cout << "Complex()..." << endl;
a = 0;
b = 0;
}
Complex(int a, int b){
cout << "Complex(int, int)..." << endl;
this->a = a;
this->b = b;
}
~Complex(){
cout << "~Complex()..." << endl;
}
void printComplex(){
cout << "(" << this->a << ", " << this->b << "i)" << endl;
}
// 方式二:在类内部实现(方式一和二是一样的,所以只能保留一种)
// c1 + c2 的写法会同时匹配这两种实现方式,如果都有实现就会产生二义性
// 不能返回引用类型
// + 操作符重载
Complex operator+(Complex &c2){
Complex temp(this->a + c2.a, this->b + c2.b);
return temp;
}
// += 操作符重载
Complex& operator+=(Complex &c2){
cout << "operator+=()..." << endl;
this->a += c2.a;
this->b += c2.b;
return *this;
}
// 前++ 单目运算符,因为可以进行连续前++操作,所以返回引用类型
Complex& operator++(){
this->a++;
this->b++;
return *this;
}
// 后++ 单目运算符,不能进行连续 后++ 操作,返回类型加const
// 为了与 前++ 进行区分,使用亚元形参
const Complex operator++(int){
Complex temp(this->a, this->b);
this->a++;
this->b++;
return temp;
}
// = 操作符重载
Complex& operator=(Complex &c){
// 1、是否与自身相同
if(this == &c) return *this;
// 2、如果自身有开辟内存,就清理自己的垃圾
// 3、深拷贝
this->a = c.a;
this->b = c.b;
return *this;
}
// [] 操作符重载
int& operator[](int index){
if(index == 1){
return this->a;
}
if(index == 2){
return this->b;
}
throw "error index";
}
// == 操作符重载
bool operator==(Complex &c){
return (this->a == c.a && this->b == c.b);
}
// != 操作符重载
bool operator!=(Complex &c){
return !(*this == c);
}
// () 操作符重载,仿函数
bool operator()(){
return (this->a != 0 && this->b != 0);
}
// new 操作符重载,会传入所创对象的大小(sizeof(Complex))
// 返回的是 void* 的指针
// p->operator new(sizeof(Complex))
void* operator new(size_t n){
void* p = malloc(n);
cout << "重载了 new... 空间大小是:" << n << "\t指针地址是:" << p << endl;
return p;
}
// new[] 操作符重载,这个 n 多了一个指针的大小,不知道为什么?
void* operator new[](size_t n){
void* p = malloc(n);
cout << "重载了 new[]... 空间大小是:" << n << "\t指针地址是:" << p << endl;
return p;
}
// delete 操作符重载,会传入所要删除的指针,类型是 void*
void operator delete(void *p){
cout << "重载了 delete... 指针地址是:" << p << endl;
if(p != NULL){
free((Complex*)p); // 应该也可以不用强转,在 malloc 时会管理一张程序内存分配表,里面有分配指针所对应的大小
p = NULL;
}
}
// delete[] 操作符重载,会传入所要删除的指针,类型是 void*
void operator delete[](void *p){
cout << "重载了 delete[]... 指针地址是:" << p << endl;
if(p != NULL){
free(p);
p = NULL;
}
}
// && 操作符重载(不建议重载,因为不会发生短路现象)
bool operator&&(Complex &c){
return ((*this)()) && c();
}
// || 操作符重载(不建议重载,因为不会发生短路现象)
bool operator||(Complex &c){
return (*this)() || c();
}
private:
int a; // 实部
int b; // 虚部
};
#if 0
Complex complexAdd(Complex &c1, Complex &c2){
Complex temp(c1.a + c2.a, c1.b + c2.b);
return temp;
}
// 方式一:用全局函数重载(友元重载)
Complex operator+(Complex &c1, Complex &c2){
Complex temp(c1.a + c2.a, c1.b + c2.b);
return temp;
}
Complex& operator+= (Complex &c1, Complex &c2){
c1.a += c2.a;
c1.b += c2.b;
return c1;
}
#endif
// 左移
// 只能用全局函数实现重载,如果在类内部实现,调用形式就成了 c.operator<<(cout)
// 因为可以连续调用,所以返回 ostream 对象引用
ostream& operator<<(ostream &os, Complex &c){
os << "(" << c.a << ", " << c.b << "i)" << endl;
return os;
}
// 右移同理
istream& operator>>(istream &is, Complex &c){
cout << "a: ";
is >> c.a;
cout << "b: ";
is >> c.b;
return is;
}
int main( )
{
Complex c1(1, 2), c2(3, 4);
c1.printComplex();
c2.printComplex();
// Complex c3 = complexAdd(c1, c2);
Complex c3 = c1 + c2 + c1; // 方式一等同于 operator+(c1, c2);
// 方式二等同于 c1.operator+(c2);
c3.printComplex();
cin >> c1; // operator>>(cin, c1)
cout << c1 << endl; // operator<<(cout, c1)
cout << c1[1] << endl;
c1[1] = 5;
cout << c1;
try{
c1[0] = 0;
}
catch(char const *e){
cout << e << endl;
}
if(c1()){
cout << "c1 is valid" << endl;
}
else{
cout << "c1 is not valid" << endl;
}
// 测试数组
cout << "静态数组大小是:" << sizeof(Complex[2]) << endl;
Complex *cArray = new Complex[2];
// 这里的地址比 delete[] 的地址高了一个字节,不知道为什么?
cout << "首地址是:" << (cArray - sizeof(char)) << endl;
delete[] cArray;
// 测试 && || 是否发生短路
c1[1] = c1[2] = 0;
if(c1 && (c1 += c2)){ // c1.operator&&(c1 += c2)
cout << "真" << endl;
}
else{
cout << "假" << endl;
}
cout << "============" << endl;
c1[1] = -3;
c2[2] = -4;
if(c1 || (c1 += c2)){ // c1.operator||(c1 += c2)
cout << "真" << endl;
}
else{
cout << "假" << endl;
}
return 0;
}
输出:
(1, 2i)
(3, 4i)
(5, 8i)
a: 10
b: 20
(10, 20i)
1
(5, 2i)
error index
c1 is valid
重载了 new... 空间大小是:8
Complex(int, int)...
对象 c1 的地址是:0x5641c235a2c0
~Complex()...
重载了 delete... 指针地址是:0x5641c235a2c0
静态数组大小是:16
重载了 new[]... 空间大小是:24 指针地址是:0x5640c52efeb0
Complex()...
Complex()...
首地址是:0x5640c52efeb8
~Complex()...
~Complex()...
重载了 delete[]... 指针地址是:0x5640c52efeb0
operator+=()...
真
============
operator+=()...
假