你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

C++——操作符重载

[复制链接]
gaosmile 发布时间:2020-8-13 21:23
一、操作符重载:
1、我们先来看一个问题实现,下面的复数解决方案是否可行,复数大家应该都不陌生(分为实部和虚部):
class Complex
9 t+ y$ Z/ [6 n8 e* E+ i{
6 P6 C  ?/ M, f' _1 V   public:2 w* J. }, a  }/ x' s. l$ [
         int a;4 x) i" B, J' f# [6 u& K
         int b;$ F9 I. t4 Q+ b) C, a
};0 p7 b' b7 M. }8 E3 P

) c: x; u4 q+ o9 v  c! C+ j/*--------------------------*/; t# W# _% d+ ^3 X  s' M
int main(). |; I' k4 d) K8 B" H
{$ x, j! m: Q5 N3 n$ u1 @) d$ M
   Complex c1 = {1,2};
0 w# C7 |# Z; V+ I% P   Complex c2 = {3,4};
: {4 h( L6 H: h7 G: e( f4 c" D7 e  L   Complex c3 = c1 + c2;//也就是复数的实部加实部,虚部叫虚部。0 r/ g5 c1 ~) H* W5 n6 _) ]/ ^
   
' W: H7 d; m/ u   return 0;
! y9 H* j) P3 G! C( M7 i: C}  h; H& t) U) O

' S' r% _' w6 u0 z3 o5 @注:成员变量为公有且没有自定义构造函数的时候,可以通过大括号来分别初始     化成员变量;
, @+ F9 @. }$ l4 k, \$ v5 F; w
5 X4 P; k& p" l# L' d$ q
代码版本一:
#include <stdio.h>' j. `- v8 O8 t9 V8 C: z
( q* e! p; i/ g/ `6 R
class Complex
% z/ P0 N1 {# J{
3 _* y4 Y+ {# |% E    int a;# ?% u5 c4 W3 ?/ h& B4 W
    int b;
1 K% F+ [6 A5 Ipublic:7 z3 p$ h2 x, w: ~
    Complex(int a = 0, int b = 0)' o# C& D/ e! K! M; X
    {
" [! ~$ c4 g: P% T        this->a = a;
$ ?( j5 [7 f( H  Y8 Q: \        this->b = b;6 y: G& f! V6 t6 L! O) }
    }7 d5 T& b. J1 m/ q( k/ j
   
) B) `9 F* ?$ g$ W    int getA()
8 w: ]. k% w# d% [# e5 s    {/ I( N+ D" S7 `0 Q
        return a;& M2 D) b* c- N7 `- i- i
    }3 q! M2 N7 p' f5 ]6 \( J$ h
   
% e2 j, p# ]1 u8 C! A1 q3 Y7 b4 ^    int getB(): k+ |+ Q, m5 h% m; K. Q7 w
    {  `6 ?1 O; u- P; X
        return b;9 G2 h) U: a, c0 V- y" m
    }8 L/ u$ z; O' _& J9 F; U8 y3 A7 y7 p
    1 v3 I: }/ R( R7 @! @3 S( o
    friend Complex Add(const Complex& p1, const Complex& p2);# u, M  O: f" B# \
};
% `; A& }, O( J" m# [
' a- r8 T- \! N- z) `Complex Add(const Complex& p1, const Complex& p2)# u1 {5 h) u2 Y' B+ f1 q
{
8 p9 E4 L7 x0 y3 @) x; N9 x    Complex ret;
( m7 [' g* }1 U& Y5 p    , J0 ?3 G1 D% `) ^$ i" O" K
    ret.a = p1.a + p2.a;$ l5 w' |3 i% Z; A+ m
    ret.b = p1.b + p2.b;
( r7 n. h, V6 N$ H    # w' G  ]$ n  j
    return ret;
4 v# d( {2 v" i2 Q}
, J3 I5 A) Z1 u2 Z. k
' W( [2 M9 `; h2 qint main()
4 i/ ~0 S& ~9 b' I0 X7 F! ~{8 `$ n  h9 e& M; [
. ~. D" k% d* Z1 q0 ?: R
    Complex c1(1, 2);$ T/ }9 l- n. T" W) A" [4 z
    Complex c2(3, 4);$ M2 k) Y. C3 A  L, @8 K* Z$ I' Q
    Complex c3 = Add(c1, c2); // c1 + c2
, Z! c: c* t! w   
# B2 I, \% I9 `7 s    printf("c3.a = %d, c3.b = %d\n", c3.getA(), c3.getB());
2 d0 \8 ?, b( \6 x9 k   
6 U1 _' R) Z/ _. q. m    return 0;. J9 T- i5 U# q+ Q2 |! N* F
}
2 \5 I6 V) u$ \
& y" F) m% _- P; Z" b# N( {+ R
运行结果:
root@txp-virtual-machine:/home/txp# ./a.out( \* {: w: \2 C1 I2 s* @7 V% V2 T
c3.a=4,c3,b=6
9 g# r8 D) M, q# T" @) k# X  u8 n1 j

+ W: B+ P3 ]/ m* U! x3 `
这里通过Add函数可以解决Complex对象相加的问题,但是在我们数学运算里面就是直接实部加实部,虚部加虚部,和正常的实数相加一样,所以说,为什么不直接这样操作呢,这就涉及到符号"+"的问题。
2、操作重载符的引出
  • c++中的重载能够扩展操作符的功能
  • 操作符的重载以函数的方式进行
  • 本质:用特殊形式的函数扩展操作符的功能

    & j' x1 E2 b- \' R: G
3、操作重载符的语法:
  • 通过operator关键字可以定义特殊的函数
  • operator的本质是通过函数重载操作符
  • 语法格式:
    * ]+ C; M9 f) @( q4 o$ e
Type operator Sign(const Type& p1,const Type& p2)
: k/ b: K* K$ y2 {) C0 q{
  q  v# e3 {4 ]" }3 b7 V' r      Type ret;
) R2 s+ X9 a" ]: x' o7 u. W, b7 @      . l7 W+ u8 b0 Y: x' d
      return ret;
% i) `. v" x3 D- A6 i}' A8 q3 Z' R3 K- b/ \

  b9 H6 Q9 h) `- L- k0 T* x注:Sign为系统中预定义的操作符,比如:+、-、*、/ 等
1 \  q2 W7 m' x9 ^
代码版本二:
#include <stdio.h>$ g; \( ~8 X" B, [# Q

( o9 A( K; L1 n3 aclass Complex 0 B3 s2 w) U  s; H6 l
{" U+ J/ _$ c) }
    int a;4 }0 _2 j: f6 V& ]
    int b;
  {' q6 J, ?* P  B/ r$ _8 lpublic:
  @0 @- z) \% W, b( a% K    Complex(int a = 0, int b = 0)0 D/ f  C" f4 e: R$ o8 ~
    {
9 g+ X5 [1 V3 o0 R& }        this->a = a;
$ A2 y  [1 p' J& O1 }- O6 U: I5 g- V        this->b = b;* h  `$ q9 Z* u: j8 f
    }9 ^; D. Y9 W0 c- R5 n
   
3 G( S# x# E; ^; r6 p  v# F    int getA()
/ V7 a# ]( U: A- p    {' a$ l6 ?: U& p- _3 ?
        return a;# j$ p, \5 ~( t9 h! X
    }# n- Q4 A' v' I$ e
   
9 V7 U' c2 M6 H4 y+ G- g. }    int getB(); E; c( E/ m, b& a  R0 T
    {2 P- Z/ A- o& P
        return b;5 N6 z" _. o, w* q, I9 e
    }
2 E# D+ H! J* J' t" x    + N$ I& }2 P& n  O/ W6 w
    friend Complex operator + (const Complex& p1, const Complex& p2);
+ p8 H6 m7 k5 J# `1 F};
6 b. q. R; m4 \/ e' ?! ?% z, J) Y2 N9 E1 A* f" c
Complex operator + (const Complex& p1, const Complex& p2)
$ D3 e8 `, N1 O: ^& I6 M{& q/ W( ]' Q( a& E
    Complex ret;
0 o3 g' `! |2 ~7 T* {   
  {" ^# b8 U1 m& m. d    ret.a = p1.a + p2.a;
* w9 n! o( G' X3 P! b- J% u    ret.b = p1.b + p2.b;
% R/ r! j2 C; H. u    * Q' w4 W8 A2 n. a
    return ret;
! T2 z( r/ ?; O}
& k$ O/ r5 O$ R5 \+ v" @/ Y
- K' k! n/ p$ u- P8 n5 V+ G- Dint main()4 P. r5 ~6 m* ~) p
{6 g1 q3 h' }, p/ v4 p  a
5 ^4 w0 {. I: H, a8 c: b2 Z. u
    Complex c1(1, 2);- I2 q: X' _: R! j6 Q: W& ]
    Complex c2(3, 4);
0 b# h5 G" z& V, T) P1 n0 V    Complex c3 = c1 + c2; // operator + (c1, c2)
3 A! [2 U- }" _/ M    ; ], p. ^6 S4 ^& C9 |) U
    printf("c3.a = %d, c3.b = %d\n", c3.getA(), c3.getB());
" K0 x& M/ `, d9 G   
1 T& U# a) g% ]+ ?. p3 f- q' i' B5 i    return 0;/ ?" A' I/ s; r, T' |$ E" E$ g* m
}" ?. \/ O' |" ~# F) }6 p/ ?1 k9 j0 b" \

# }1 q& z: G4 J# k5 V% c# d# z
输出结果:
root@txp-virtual-machine:/home/txp# ./a.out
9 v5 E1 o, m5 o0 ^3 Uc3.a=4,c3,b=6
, Q9 h: B. R# W/ x3 l" p3 \

, e6 j6 g' d% g
4、再次改进代码:
  • 可以将操作符重载函数定义成为类的成员函数(前面我们学过,友元现代软件开发不允许)
  • 比全局操作符重载函数少一个参数(左操作数,成员函数中隐藏的 this 参数可以充当左操作数的角色)
  • 不需要依赖友元就可以完成操作符重载
  • 编译器优先在成员函数中寻找操作符重载(一旦在成员函数中找到,就不会去全局找)

    5 a4 n2 p4 M# s* X0 p$ y+ Q
class Type
$ _; @' m2 _( F  D$ `" c3 i/ ~{: V1 o% A  F; c& X+ S7 ^# g
   public:! P. j% z) U0 ?+ i  g
      Type operator Sign(const Type& p)# b4 S: J. {3 U8 U5 U# u2 `7 _: _
      {
6 {$ Y2 ^6 E) f  i, `0 a4 H( P          Type ret;! N% F0 {' q% ?) g( s$ e
          return ret;
' @4 P: s( i) V+ @      }
6 f" l: W$ G5 u8 ]};
* i. N5 M% Y! g  ]0 {/ c0 b. @" K
代码版本三:
#include <stdio.h>
0 T1 S$ K2 q+ _( a' C/ p0 a
( a2 o" Y# x( }  O. s6 zclass Complex 0 r0 A) w: b; _' D& C
{
' o% U& ~/ T4 r+ `    int a;4 c* Z2 u" Q3 @  W1 O! {
    int b;5 ]' i  K+ I  J% O
public:/ n# H5 f/ _7 x
    Complex(int a = 0, int b = 0)
* l, k, x; d1 ^) W6 O5 S    {
: ~7 ]' y" n3 j7 x5 e% C        this->a = a;, z; H% ?6 ?* u* g! J8 X2 c. D) v
        this->b = b;( b( [3 b% V: H  r$ g- M* p
    }( J+ M( |6 b, y2 t
    ( H9 t- T: L- w" W& \
    int getA(), g  Z" U: b  h) z6 n
    {) P! ^! M( ]2 \  B8 P
        return a;: u; I9 s# p# [0 A+ C% f) @
    }$ v! [, M& k# g6 |+ ^& S
    . s" {1 f: C9 d# y# Y
    int getB()* Y- \$ r/ X) x: r
    {
. ~0 Z. U7 o( V: W+ h. z5 l! P        return b;$ y2 }0 L( Y, D! ^1 J
    }
/ l/ j% z* s/ `1 T    8 S# B6 ^7 D/ B/ u: l
    Complex operator + (const Complex& p)/ G9 X( G# @! p: w1 P# D6 ~+ {
    {: b/ u# w' p0 O* r- f
        Complex ret;9 O3 b0 x1 ~% w- w* z+ }2 I. H' V
        printf("Complex operator + (const Complex& p)\n");
6 k/ d3 S7 j- U* u        ret.a = this->a + p.a;
! x/ H4 H. X1 t) y3 g1 @: |# E4 }+ H        ret.b = this->b + p.b;
' w' w0 l" X+ v8 w7 a8 Q        6 `7 a8 N* C( o
        return ret;
( e3 N" E' B+ y, s2 @    }
, N# O. }0 G2 }& Q   
# p: ^  O) U; Y% a! C, `- j, d    friend Complex operator + (const Complex& p1, const Complex& p2);7 v3 k( p. n8 Y
};
! u: D3 ]$ ^& m( e
5 |, B" d8 ~" u! W  yComplex operator + (const Complex& p1, const Complex& p2)
6 p' ?- N: J; J: i  E3 e- Q{
9 r- B! G8 Z1 b+ }4 q" @    Complex ret;. |8 n- f' y% c: h% r
    printf("Complex operator + (const Complex& p1, const Complex& p2)\n");
. ^; B2 m' l* U8 Q    ret.a = p1.a + p2.a;
1 y. d# S, a( i) s8 k5 Z$ K& ~    ret.b = p1.b + p2.b;
. N9 H7 U: t- {, H6 t4 n    & K9 `3 v  C- W( t3 I
    return ret;* k( D! |8 |' P
}
* B4 Y0 a9 W! q! Q; J' ]" }/ }, \) `8 q
int main()
% I! _7 U6 Z/ _0 h$ X  E{7 e0 V0 X4 j. X5 n! ^4 P, \* A& Z
' h/ E6 [5 N3 Y* ?
    Complex c1(1, 2);& V! ]) {  c9 H
    Complex c2(3, 4);6 U) g& |4 V2 R2 D, A$ s
    Complex c3 = c1 + c2; // c1.operator + (c2)
) ]; x2 w5 k5 T. i1 {    . ^7 Y; I" g- r# W
    printf("c3.a = %d, c3.b = %d\n", c3.getA(), c3.getB());
) ^/ C1 u; }% j& F4 A* ^4 a/ Q    ( v. ^& k7 C3 a& d" x) W
    return 0;6 q* U6 Y5 b. y5 b. U2 n. H$ x
}
7 T' @6 O8 Y1 T5 o4 |. w

. _, M) g8 a2 m$ b% ^
输出结果:
root@txp-virtual-machine:/home/txp# ./a.out# B5 \, |" Y3 n% A6 l0 x2 H; N* `
Complex operator +(const Complex& p)- L. O) N& Q6 s# V
c3.a=4,c3,b=6/ \; N3 k9 f) s$ [3 }5 G

6 }  G3 o! _; J2 Z3 r: e+ ^8 h
二、总结:
  • 操作符重载是c++的强大特性之一
  • 操作符重载的本质是通过函数扩展操作符的功能
  • operator 关键字是实现操作符重载的关键
  • 操作符重载遵循相同的函数重载规则
  • 全局函数和成员函数都可以实现对操作符的重载

    5 E5 l. d& [( I
好了,今天的分享就到这里,如果文章中有错误或者不理解的地方,可以交流互动,一起进步。
赞 收藏 评论0 发布时间:2020-8-13 21:23

举报

0个回答

所属标签

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版