跳转至

C++ 笔记 | 第4课 操作符重载

二目操作符的成员函数

C++
1
2
3
4
5
6
7
8
complex complex::operator+(complex c2) {return complex(r + c2.r, i + c2.i); }

// 或
complex complex::operator+(
    const complex
        &c2) {  // 引用可以提高效率,const 修饰符可以确保引用方式不带来副作用
  return complex(r + c2.r, i + c2.i);
}

二目操作符的友元函数

C++
1
2
3
4
5
6
7
8
9
// 类内
friend complex operator+(complex c1, complex c2);
// 类外
complex operator+(complex c1, complex c2) {return complex(c1.r + c2.r, c1.i + c2.i);
}

// 或
friend complex operator+(const complex &c1, const complex &c2) {return complex(c1.r + c2.r, c1.i + c2.i);
}

单目操作符的成员函数

C++
1
2
3
4
// 前置单目运算符重载
void operator++(){ ++num_;}
// 后置单目运算符重载
void operator++(int) {num_++;}

单目操作符的友元函数

必须使用引用,否则无法改变相应对象的值

C++
1
2
3
4
5
6
// 类内
friend void operator ++(Clock &c);
friend void operator ++(Clock &c, int);
// 类外
void operator ++(Clock &c) {++c.num_;}
void operator ++(Clock &c, int){c.num_++;}

特殊操作符的重载

C++
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// 类内
String &operator=(String str2);
// 类外: 对等号运算符进行重载, 从而进行地址的深复制 (类似自己实现的复制构造函数)
// 这种方式不支持 str2=str2 或 (str2=str1)=str2
String &String::operator=(String str2) {delete[] this->p;
  this->p = new char[strlen(str2.p) + 1];
  strcpy(this->p, str2.p);
  return *this;
}

// 所以需要进一步改写 = 操作符重载函数为:
String &String::operator=(String &str2) {char *q = new char[strlen(str2.p) + 1];  // 先申请新内存 q
  strcpy(q, str2.p);  // 把 str2.p 所指字符串复制过去
  delete[] this->p;   // 删除当前对象中 p 所指内存
  this->p = q;        // 让当前对象中 p 指向新内存 q
  return *this;
}

// 也可以写为
String &String::operator=(const String &str2) {if (&str2 != this) {delete[] this->p;  // 删除当前对象中 p 所指内存
    this->p = new char[strlen(str2.p) + 1];  // 申请新内存
    strcpy(this->p, str2.p);  // 把 str2.p 所指字符串复制过去
  }
  return *this;
}

<< 操作符的重载

函数参数和返回值都必须是 I/O 对象的引用,而且只能将 <<>> 重载为类的友元函数

C++
1
2
3
4
5
6
// 类内
friend ostream &operator<<(ostream &, complex &);
// 类外
ostream &operator<<(ostream &output, complex &c) {output << "(" << c.r_ << "," << c.i_ << ")" << endl;
  return output;
}

类型操作符的重载 (double)

如果想把复数 complex 类对象 c 的实部当做普通 double 数进行运算,则需要 double(c)--- 类型转换函数,把一个类的对象转换成另一个类型的数据

类型转换函数只能作为相应类的成员函数

类型转换函数要慎用 (因为运算符优先级问题)

C++
1
2
3
4
5
6
// 一般形式
operator 类型名 ( )
{return 与类型名类型相同的转换结果;}
// 把复数 complex 类对象 c 的实部当做普通 double 数进行运算
operator double( ) // 类型转换函数
{return r_;}

重载 ++,-- 操作符函数的返回值

C++
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// 重载为成员函数
complex &complex::operator++() {
  r++;
  i++;
  return *this;  // 返回当前对象
}
complex complex::operator++(int) {
  double rt = r, it = i;
  r++;
  i++;
  return complex(rt, it);
}
// 重载为友元函数
complex &operator++(complex &c) {
  c.r++;
  c.i++;
  return c;  // 返回所操作的 c 对象
}
complex operator++(complex &c, int k) {
  double r = c.r, i = c.i;
  c.r++;
  c.i++;
  return complex(r, i);
}