还有类型转换函数

#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+=()...
假