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

C++中的函数重载及进阶学习

[复制链接]
gaosmile 发布时间:2020-8-10 22:17
一、C++中的函数重载:
1、函数重载的概念:
  • 用同一个函数名定义不同的函数
  • 当函数名和不同的参数搭配时函数的含义不同
  • 注意:在c语言中是没有函数重载这个概念的。
    ) ]' e0 n+ X+ I7 i. A( L8 E
代码示例演示:
#include <stdio.h>; F0 v# {3 F/ F, C6 g( x/ X
#include <string.h>
  i6 q( f' G% \2 ]int func(int x)
! M/ S6 O) k' K1 E$ Q, M1 E% T9 W{
6 X# z0 |, Q4 V6 ~; T+ r2 N    return x;# K! M: V- ]# Y
}
1 K* W. D0 r/ |; @0 ]! W8 \9 Q4 }) i$ M) w( ]7 E: d
int func(int a, int b)
4 b( E) D& s+ f5 Y{
5 R5 H7 A; Y* c9 W# s: R   return(a+b);
1 h7 F3 E3 d2 X$ a3 G}, V: Y+ M8 p# W

. R% K0 v( D: X1 [int func(const char* s)2 C9 ?# g4 U/ z% Y' D
{
4 C0 m/ x# a/ c5 Y& N3 q9 Y9 p    return strlen(s);) M0 }/ B+ d' M# T
}/ x; v1 x" _5 `! V8 K5 }! F0 Y4 _

6 U6 Z4 z1 G: Q$ P1 L, i# r4 U9 G) y! Xint main()4 @+ x! p' a, e* p
{
8 c: l4 Z: p7 E" X1 F$ r: @* B& V5 f1 Q. r+ u" o, U/ w1 A0 L. O
   return 0;
( Z+ u! N5 Q, C0 z8 Z5 A% B
# V2 _% e2 n) G}
7 P2 \1 y0 t; ~) J* d$ e
0 ?  ~$ y* X3 ^5 o
上面在c++编译器里面编译时没有问题的,如果放在c语言编译器里面编译是会报错的:
root@txp-virtual-machine:/home/txp# gcc test5.c. b! b' \+ {* F1 P+ {& t
test5.c:8:5: error: conflicting types for ‘func’
7 M" e: }' U  s1 ~$ |" ?! M% h$ F& | int func(int a, int b)! |! ~% K4 v; i$ H( k; x
     ^5 f" @6 _0 a+ d5 o
test5.c:3:5: note: previous definition of ‘func’ was here
( M( X( \. n8 @$ l int func(int x)$ Q$ ~* [9 |9 m  {) g$ n
     ^9 M- n" x1 u. \* }
test5.c:13:5: error: conflicting types for ‘func’3 O2 z  M* o9 Y* `; |; t% _
int func(const char* s)
+ p9 q" {+ Z+ S9 j0 |     ^
  o" b4 x2 Z' K4 Qtest5.c:3:5: note: previous definition of ‘func’ was here
4 _- \# I1 C# [! d# @1 f. l int func(int x)
; U$ T/ R: y/ e# ?
6 p8 v0 _% ?, o8 y! J" i
所以说c语言里面不支持函数重载。
2、函数重载至少要满足下面的一个条件:
  • 参数个数不同
  • 参数类型不同
  • 参数顺序不同

    1 v4 i+ U9 Q5 z% }" G
比如下面两个函数可以构造重载函数吗?
int func (int a,const char* s)
* f$ Q4 t* ~! _/ ]) q{8 o) P6 z( s* |6 D
   return a;+ C! Q0 }) D6 @7 |- x, t  w" G
}
- `5 _( g5 E# U4 j! Q& S3 c8 H: g8 L6 G* D
int func(const char*s,int a)$ U% x' N" K6 G- \: H) U6 C0 x
{3 V5 W0 o/ Z  @2 j5 L: l
    return strlen(s)6 J+ ]8 a2 T" G( }' v6 S
}

) P1 c6 g" O4 x6 F/ V8 ~0 a/ o. h
答案肯定是可以构造重载函数的,读者可以自己试试(这个比较好理解)。
3、当函数默认参数遇上函数重载会发生什么?
例如下面的两个函数:
int func(int a, int b, int c =0)# y" I: p5 B7 D: C1 s/ M8 x
{
( [9 l5 b9 N; p8 `' B3 U, S* d    return a*b*c;
2 z; x; J, F0 [}
* Y  c# U7 D$ d3 v) a9 x6 bint func(int a, int b)
  r4 u1 G7 F/ r2 `0 I  W{
& }8 \7 \( W  ^9 I   return a+b;) J8 f# r/ U. b
}
3 i7 D2 M7 S9 X5 d! Z) j! ?
$ z; ~: X' N+ S  d
到底会发生啥,我们还是看下面这个实验:
#include <stdio.h>
" N! c' ^" y7 L6 `6 X3 `6 \& P# K. c& S- ~: `
int func(int a, int b, int c = 0)) i. l* H$ M: @, ]6 }( u( l' `
{
$ Y% J0 _* [7 U! ?: _* n    return a * b * c;; ~  ]( @# W- @/ d4 c
}
' ?1 i, q1 n% s4 w8 `8 u. t8 i3 G0 Q1 X
int func(int a, int b)
. J* V4 e" A0 ~6 h$ F. B2 P{
" {8 z0 k4 W! n    return a + b;
7 E5 c' P# ^) ]$ C) y}1 I4 Q% \- D/ h2 Q9 V- h7 G8 ]
' q) f+ _3 a& h8 i" G

3 h! k- i6 U7 N+ O& ~: \* Hint main(int argc, char *argv[])
0 V# X9 P# m( C) b  N* k{
/ L" F4 D& ^+ H, P& d    int c = func(1, 2);  `5 G; b( m7 k/ k3 g1 K
   
9 `" {# B& L3 S, {# s% S& h+ Q' Y    return 0;6 g  g( j# E! p2 a' Y8 ^
}
7 U' N# O7 u: t7 Y
0 r  p6 ?  B$ x
运行结果:
root@txp-virtual-machine:/home/txp# g++ test5.cpp
; y$ Y& b8 d1 utest5.cpp: In function ‘int main(int, char**)’:
2 m. ?9 Q/ _+ D4 I& J+ a1 ^test5.cpp:16:22: error: call of overloaded ‘func(int, int)’ is ambiguous
2 u+ z* ?$ y7 v     int c = func(1, 2);
, X" A8 R8 A8 w5 k; |0 |' O; A                      ^
3 M4 }7 {! W" l3 ~4 Gtest5.cpp:16:22: note: candidates are:. u5 _9 V* K( c6 _- s0 a+ h$ W: J
test5.cpp:3:5: note: int func(int, int, int)
% f2 V8 [* V/ j. G/ V4 ], S" ?$ ` int func(int a, int b, int c = 0)/ Y# j! m1 K; [. A( f" _
     ^
0 u' v! B' D4 I9 ]- V& ~# Ftest5.cpp:8:5: note: int func(int, int)" i  E3 L3 R# {+ ]
int func(int a, int b)+ ~0 g# }0 J+ h& F6 f6 w' A& _
+ _4 o: t! Q. c; \) T
从上面报错的结果里面有一个单词ambiguous(意思是梦棱两可的),也就是说默认参数这种使用时不允许的。
4、C++编译器调用重载函数的准则:
  • 将所有同名函数作为候选者
  • 尝试寻找可行的候选函数:
  • 精确匹配实参

    : Z# j' ^/ _/ z) W
       通过默认参数能够匹配实参
      通过默认类型转换匹配实参
  • 匹配失败:

    ' `6 V7 Z2 ?; T5 w& C/ s
      最终寻找到的候选函数不唯一,则出现二义性,编译失败
      无法匹配所有候选者,函数未定义编译失败
5、函数重载的注意事项:
  • 重载函数在本质上是相互独立的不同函数
  • 重载函数的函数类型不同
  • 函数返回值不能作为函数重载的依据
  • 函数重载是由函数名和参数列表决定的

    3 U' }! e$ X) n* s
代码测试:
#include <stdio.h>- ?; y! w4 X6 T* t5 f
( G6 F! {3 Y) Y/ W
int add(int a, int b)  // int(int, int)2 J1 j, O9 d5 K, h
{
8 |, L- \) g  G4 P5 v$ I4 a) v, ]    return a + b;
$ `. i" K6 p/ L# J% r}0 P4 G7 p1 z: A' A

7 W6 F7 B4 G/ |4 fint add(int a, int b, int c) // int(int, int, int)
" i  C! ~7 C, G0 T- u{
4 L6 z4 K& }& c0 x9 K+ r9 a/ N$ Y    return a + b + c;
+ W$ `6 Z3 [" j3 M; P. e}9 ]: R- V1 }! U; X* r6 N, g8 e" Z  Z
5 ^( t1 Q9 _7 o) b' ?9 T
int main()
! K* d* Y2 I- I  Y. k6 J{8 E, n+ z/ p/ j! \/ |5 w% M; T
    printf("%p\n", (int(*)(int, int))add);
& V- a# k0 B( b6 \    printf("%p\n", (int(*)(int, int, int))add);  V: R5 x* [2 \- K+ a+ Y+ v" Z
8 x' f6 G, x! U4 m% E
    return 0;, w5 X+ m% k3 v' `- W
}

7 N9 [: x" b+ s3 r/ [; |. ~
运行结果:
root@txp-virtual-machine:/home/txp# ./a.out/ ]) J! M9 L4 J5 c
0x40052d
2 e& E2 r- q: T% u2 e0x400541
; f" T8 y, C4 Y

' V, S' [4 h- \( I8 ?- v. b/ q
从输出结果我们可以看出这两个函数的入口地址不一样,这表明这两个函数是不同的函数。
6、小结:
  • 函数重载是c++中引入的概念
  • 函数重载的本质是相互独立的不同函数
  • c++中通过函数名和函数参数确定函数调用
    5 v9 l& b9 t( Z- Q
二、重载函数进阶学习
1、重载与指针:
下面的函数指针将保存哪个函数的地址?
int func(int x)( v1 J7 \0 \- _  [! {
{5 L2 ?8 A2 V" d4 M% i) s
    return x;
4 H. C! {. U. Y}$ f/ w6 G5 i8 H( j
int func(int a, int b)
$ [  q: M2 b+ `8 F; U7 V* b{# P1 e. d( i2 Y
    return a+b;" @8 ~9 K7 k" i0 p
}: @: {6 u2 x( h* N3 s( P+ R
int func(const char* s)
6 i. N7 q3 a% Z{4 n3 }5 z7 i3 n7 r0 a
  return strlen(s);
* V+ g0 F5 b. Y( k3 o6 [: g# ?}; R: `6 v- A2 m" f! b
* n: [1 _5 _8 U, J& \$ X9 V4 z  C0 b
typedef int (*PFUNC) (int a);  m" `' L+ z; ?" k" K! X. Q) M

6 |6 Z8 z6 k/ @; Fint c =0;1 u  Q5 d  S$ A* L  B
/ }: i* w1 n) x
PFUNC p = func;; }6 K: D' M( z9 W  o' _/ e. l9 J! f! ]

. b$ D+ [$ Q" I6 Z9 I8 Sc = p(2)//到底选择哪个func函数
& r9 x/ O! n) M- J/ n/ n2 Z

4 T! G. K9 X  D# {( p, e4 k, k
函数重载遇上函数指针:
  • 将函数名赋值给函数指针时
  • 根据重载规则跳线与函数指针参数列表一致的候选者
  • 严格匹配候选者的函数类型与函数指针的函数类型

    6 z" X% Z) ?  C
代码试验:
#include <stdio.h>
" G. f& o- |( e6 Q, E#include <string.h>
% ~, d- A+ v# M4 A1 x2 u% L
; J6 u9 U7 p4 R9 y7 o. }int func(int x)
4 b$ C) z, b1 p( C4 K0 m( u* r( p/ _{! X; B3 I$ x8 F: [2 q  j) F3 E/ J
   return x;
6 j. }1 }5 [8 Y7 d5 `; h* {  L  G}
( c! E' `7 u3 S; Y% M+ l2 O* g' S. N0 j8 G* e+ {$ B4 `
int func(int a, int b)
- m1 d1 k$ L8 m{
( r  S: l9 ?# W3 V     return a+b;
+ U: F: ]" y3 A- q( W/ j}
/ @; b" d4 p& I) m4 i! o2 J- w. s
int func(const char* s)
. V+ k6 D8 I  F{
% d( n: c& ?: w" j' T1 w    return strlen(s);
* }  x  B! ^- _  l0 s$ y: V}
3 v0 t) q6 \7 P& N( T/ x6 Rtypedef int(*PFUNC)(int a);: V$ L/ V2 V9 i0 s, h- u

- V9 \6 ?3 i7 Z) d0 Rint main(int argc,char *argv[])5 k) [( C2 h, r6 s+ R8 u
{, V# W9 O5 [* \/ |0 C. p7 @
     int c =0;
9 z% z0 v9 j/ x+ y     PFUNC p =func;% W0 S0 U- n* r

2 I/ l$ \) c1 M! e9 t, [  F/ i7 ^8 g' X     c = p(2);2 F3 A: n: B  f
     printf("c=%d\n",c);9 J: o) R5 T1 L( Q
     return 0;8 J/ A3 O4 r( W
}
1 j8 m1 n# R8 ^& Q1 a/ p1 k

% ?! M0 \! j9 i' k0 p
输出结果:
root@txp-virtual-machine:/home/txp# ./a.out$ x9 h; w# M2 I& q! g2 @
c=2
! ^3 W3 B* |  f* t5 n

- J2 M' Q5 F% }& T2 `
从输出结果来看,很明显调用了第一个func函数。
2、注意:
  • 函数重载必然发生在同一个作用域中
  • 编译器需要用参数列表或者函数类型进行函数选择(也就是说碰到指针,要注意函数类型了)

    + I2 u: u7 a' `9 p+ O! r. `
无法直接通过函数名得到重载函数的入口地址,这里还是通过上面的例子演示一下:
#include <stdio.h>2 E; V; L: r: k% F' d* Z
' x- \  B2 L% f4 b$ K2 u& q# c
int add(int a, int b)  // int(int, int)4 [, e2 D, Y4 D$ C1 t7 a
{
  s' y6 t8 c6 h    return a + b;3 s0 b# N, r: @' ?
}: K" T. m! q1 h# x

( K/ c0 Y' L! J0 Y6 X( H# \* fint add(int a, int b, int c) // int(int, int, int)
- j' Y3 O& M: s6 j! [% F$ K{5 d  o- ]& m( l' {
    return a + b + c;2 z: H* e+ q; m  W" S
}
9 t9 J' n& i% Q, }# S+ _) C: t; h" P4 X/ o
int main()9 N' d% y# Q7 K5 X. x! J
{" w7 U# l& B0 O# C
    printf("%p\n", add);! o6 \9 u) I0 a- L% c2 s4 i
    printf("%p\n", add);1 |& c8 c/ O3 F  c/ p0 V
; k+ j0 c& G* ?9 f+ g# i
    return 0;
; o* O9 P% K  u+ h% I}
% W4 ^+ Q# p9 F" @* t+ h+ o( ]
输出结果:
root@txp-virtual-machine:/home/txp# g++ test5.cpp) x  a' O5 ~# {
test5.cpp: In function ‘int main()’:
. R! A- _3 Y/ F$ z* etest5.cpp:15:23: error: overloaded function with no contextual type information
7 E$ _. k% L3 [4 P* L- \' h6 `     printf("%p\n", add);. Q; D0 t! }' o$ ]
                       ^9 S" W( U( W: D! Y
test5.cpp:16:23: error: overloaded function with no contextual type information
3 z" r$ a+ [' i% _' @     printf("%p\n", add);8 ]. V* a! h. J5 \7 h

* z! L3 i; [# X% \& m0 G2 v* n
三、C++和C相互调用:
  • 实际工程中C++和c代码相互调用是不可避免的
  • c++编译器能够兼容c语言的编译方式
  • c++编译器会优先使用c++编译的方式

    " s! ]5 S! L8 u$ k' `
extern关键字能够强制让C++编译器进行c方式的编译:
extern "c"0 m2 s8 C# u  q- ]  s3 T  j) _
{; s" \# F, C' {* l4 h1 s5 \9 Z

" V  ^* c% W5 p1 V8 U6 ], U* S6 q  A) g/ O! q" y5 b- T) A
}! ~/ O" x. B5 L" A

5 L) z6 _  f+ X, f- E1 a  [1 Q
1、下面进行一个c++中调用c函数,这里我在当前创建三个文件:add.c 、add.h 、main.cpp。内容分别如下:
add.c内容:

  Y0 x' M7 x9 N#include "add.h"
0 w1 l1 [9 ]0 X4 xint add(int a, int b), |5 ]- `; E5 b

) d" @6 q; ?) e: ?" ^- R2 b4 U7 p{
7 j, I4 p7 C, U
6 A: `! w2 z2 I' P- q8 C/ p    return a + b;
+ L% M: l8 M( j. h: C, k3 k! Y2 |. w( o; N
}2 c- W4 a  G0 v8 ?  k- K
+ U9 U: m; \- j: k- N# Z2 [
add.h内容:
int add(int a, int b);
, e/ y3 @5 }3 ^: b$ q! D8 d
然后我用gcc编译编译生成add.o文件:
root@txp-virtual-machine:/home/txp/add# vim add.c0 j) b8 L3 P0 h9 H5 g
root@txp-virtual-machine:/home/txp/add# vim add.h
% A9 [8 M7 P, x, E# \% X1 W. vroot@txp-virtual-machine:/home/txp/add# gcc -c add.c -o add.o9 ~3 B' t) i4 O
root@txp-virtual-machine:/home/txp/add# ls5 z4 l$ }. J) L" w7 ?' C2 w
add.c  add.h  add.o
2 j% d2 Q9 J  q( C! A, U- W
  w$ A0 J6 b2 _" }5 \# ?  O
然后main.cpp里面调用add.c
#include <stdio.h>8 u4 b, M. V7 ^1 C9 r3 [1 s
int main()# V9 K* U2 M1 C/ j
{
# y/ \: C9 D% x; n    int c = add(1, 2);
2 P+ H  I* D: x  h& U) V7 M    5 v- a( f8 p) A
    printf("c = %d\n", c);7 B( V0 y+ O0 f! o+ H
   
" ?+ m# R. N6 y' \6 N    return 0;) w4 ]7 y$ V" t7 J
}
/ [( z  f2 W/ ?$ H
输出结果:
root@txp-virtual-machine:/home/txp/add# g++ main.cpp add.o  [- S4 C6 t' t( Q
/tmp/ccqz3abQ.o: In function `main':
. W) l9 m' v5 n( fmain.cpp.text+0x13): undefined reference to `add(int, int)'
: G7 |  E  v9 q  E* wcollect2: error: ld returned 1 exit status3 P- I/ @: h# O3 V
! n) T. ?$ D& Y& e& f5 E  R
2 r9 W3 N* u) u& _
结果显示找不到这个函数,为了能够在c++里面调用c语言里面的函数,我们就要使用刚才上面讲的第四点了;这里我们先用nm命令来查看一下add.o文件里面是否生成符号表(有生成):
root@txp-virtual-machine:/home/txp/add# nm add.o
! o* x  D; }! F: L) E3 H5 n8 R0000000000000000 T add' N) C! [# r: g6 P" \5 m  b
. v; @3 a5 L# H, e7 r/ G
解决方法,main.cpp改成:
#include <stdio.h>' J# T% F  f+ U* m: G' Y' x

( x% o' u9 C6 M' ]6 j) K& Pextern "c"0 M3 f8 C$ C6 n6 d. ^& _
{9 Q- D1 x: P1 Z+ |  D/ J9 E# p3 ^
    #include "add.h"; ?* \/ C5 T1 A+ m% p: Q% |; I

" y7 X+ z$ t4 s& O8 m1 I8 n6 Y}
- k6 A; j3 I$ x: D- O4 Y* T% N0 B) W! N) Q6 r* `
* Z, X# ~* T( I* [# @7 g- j
int main()
7 l5 [8 l; e  w9 N& S: [{
9 V1 ?+ ]! F0 _( F  x& k    int c = add(1, 2);
; ?. n5 @. D) U3 |& d+ G    3 y( B/ [! Z2 ~$ O; s. ^. K
    printf("c = %d\n", c);
' v: X1 C6 r1 g) r1 `" y3 V+ Q! E+ N7 }% R3 J* A( @) z
    return 0;
( H' ^7 W# F! w, Z8 b}! o% Q4 g/ g* R9 j7 |
' K2 D/ |+ |- {6 B& Z- i3 w
输出结果:
root@txp-virtual-machine:/home/txp/add# ./a.out
' j& F1 {) G. q" U( y" Dc = 33 _5 y/ x6 u  j# L4 l! V
. y$ N& U' E( c; b
2、c中如何调用c++函数:
这里我把main.cpp的内容改成:
extern "C"
4 D) ~  k$ S2 b' f! g7 i9 J& `{
. U# U) G. S8 m$ X' o3 T& ]1 N! v   int add(int a, int b);& D% t- Y: F; n$ |$ H
' y, U. \% H6 O+ O5 w% [9 Z2 v
}- z* h. R7 m# J4 X& ?
  P& l3 ?1 _1 R7 o" H2 }
int add(int a, int b)
6 ?# D/ E% q& c{
' ~5 z+ m! w) z. _    return a+b;    / W" A# U5 k9 T" N2 a) o. F
}+ C: ]9 \' Z% W

  T/ a/ V/ Y- j5 {

. h$ R  x9 z/ j% ^% K
编译输出:
root@txp-virtual-machine:/home/txp/add# g++ -c main.cpp -o test.o
* b' ]( t' i+ m1 x4 I& |/ Froot@txp-virtual-machine:/home/txp/add# nm -s test.o
: x: C6 r7 x" X& l" |0000000000000000 T add/ }0 B3 G% L9 q! Z
6 N  V% a3 D6 p

" H( D$ s# X7 v/ m) A
add.c文件内容改成:
#include <stdio.h>7 Q1 R2 H1 U# Q+ A0 I8 g) f
int main()  Z4 l4 J$ U8 a. _( N, T
{ : \5 N% |9 \  w
     int c =0;2 o  ?2 z  S, [0 O9 g- I4 e
     c = add(2,3);+ }+ d( y6 D/ U& v* l
     printf("c=%d\n",c);
! ?/ U  F1 p6 \     return 0;5 j4 c. l( k( U5 X& C; X: U
}

# r% F6 ?0 T0 K$ z3 _. t
输出结果:
root@txp-virtual-machine:/home/txp/add# gcc add.c test.o6 N6 ~5 m; D- ^# y1 i( v4 a+ `
root@txp-virtual-machine:/home/txp/add# ./a.out9 Q3 X  v* B# N
c=5
1 D8 V. ~% V' Y4 h1 E; L

8 ?# l% F8 D* i7 [2 F
3、如何保证一段c代码只会以c的方式被编译?
解决方法如下:
  • __cplusplus是c++编译器内置的标准宏定义
  • __cplusplus的意义,确保c代码以统一的c方式被编译成目标文件
    3 G* g! I$ I& f) z8 u6 A, I
#ifdef __cplusplus
* n0 @) G6 h# Cextern "C"
- ^1 d  g5 I" m0 t{
% e/ W$ N0 R% U. v. w  #endif3 i9 I9 r" B: x2 ^& y
7 i3 ]0 N( ~3 ]+ F7 Y+ S
  #ifdef __cplusplus
+ x5 W  k! C; {4 b}
' E5 \1 t1 p9 h! `& X% |#endif

% v7 e& D' k: x7 Z8 m. V# S9 u/ Z
这里把main.cpp改成:
#include <stdio.h>
" j" N0 J5 @; k2 J% l7 q; J+ g# Y4 c! \
#ifdef __cplusplus' ?/ k" H/ D% N  ?8 }
extern "C" {. X; k; h$ R) q) }7 d
#endif
; F& z' P5 H' f, [- L+ F+ V) v
0 }. _& [  r- ]#include "add.h"8 n9 M& f' b- J0 ^* \, }8 {
+ d% F0 d( m/ u% i/ e
#ifdef __cplusplus
1 W( Q6 I0 H* c" S+ n}1 R- ]1 v3 Z! l. w" Z
#endif: i2 C9 L7 R# Q3 ]: F8 {

! o) d3 i" b  ?1 ?2 Q6 r' lint main()& k4 S$ g  T' v
{
' H, X8 J5 Z/ q- A3 O# u    int c = add(1, 2);
5 F1 @$ \$ ?$ p" @    ' s/ ?) T0 |$ b6 M1 ]! @* y, s
    printf("c = %d\n", c);. Q1 q2 ~& r( ?, o6 L. ?* f
   
6 K# c: \: {& k    return 0;
# c  ]7 H0 |' c0 v* I}

" A' t7 f% c2 s  s
输出结果:
root@txp-virtual-machine:/home/txp/add# g++ main.cpp add.o
4 F% ~) U: N! T. K4 D; M" l& Nroot@txp-virtual-machine:/home/txp/add# ./a.out4 r- s4 k, ]' D
c = 3$ `  e1 B9 U) a$ v6 t3 b0 t! O

8 r3 Z# r2 c  w3 o6 Q' q1 Y
4、注意事项
  • C++编译器不能以c的方式编译重载函数
  • 编译方式决定函数名被编译后的目标名
  • c++编译方式将函数名和参数列表编译成目标名,这里举个例子main.cpp:
    ; T$ z- W/ `+ g% M
int add(int a, int b)
! Y) y+ N. S7 U1 B: h. X1 C- s{* F; s* E* v# ~" e
  return a+b;5 h" F% i7 W% u/ w8 H9 z/ o
}6 O5 \7 _0 G2 v$ K4 A4 s/ L' @+ L5 L

- f6 e9 Q7 X3 B4 U& u8 fint add(int a, int b , int c)
+ q+ k" ?2 j2 a9 B* K, m- _{3 y, `/ k: Q$ J8 T1 w+ ^
   return a+b+c;
' M  q) G' U$ V8 m1 |, n6 h% [0 R) q}

" t5 b$ p7 P: X; }% `' N
编译输出:
root@txp-virtual-machine:/home/txp/add# g++ -c main.cpp -o test.oo
5 [" N% b  }' B7 x7 u7 P( Lroot@txp-virtual-machine:/home/txp/add# nm test.oo6 J; ?0 y) ~' u2 @+ T. o& Z( i
0000000000000000 T _Z3addii
- e  O" u" s7 y+ I0000000000000014 T _Z3addiii
7 Z# R. d  U  G

( z6 B9 {* J- @# j
说明ii表示两个参数,iii表示三个参数
  • c编译方式只将函数名作为目标名进行编译,这里还是以main.cpp为例:
    . u% I/ i* A  P) m; K: D: e6 [
extern "C"4 ?) e* M- s6 j/ ?5 I
{3 z& Z/ m( T5 F# {/ H- C: g) v  U- p* S3 {
   int add(int a, int b)
" {, f8 ~1 @5 ^! B3 U  {1 |; C, L. I  ?% L
       return a+b;
6 O1 P6 A3 R6 L% i: ?; I  }- `4 n7 G) O0 {' H/ `
4 M( q$ `3 H' f6 S, Y# j: f$ D
  int add(int a, int b , int c)
8 e! V+ L1 v5 @3 Y0 L   {& L( @4 d" n$ _$ l$ ^
      return a+b+c;
, T6 [9 l& g2 c& q! T& B: U   }9 }4 Z- R: o* y. w, f& Y+ S' p
}* T$ [- p( R, q" m

6 W6 d. G! g3 ~$ a
输出结果:
root@txp-virtual-machine:/home/txp/add# g++ -c main.cpp -o test.oo
5 H& c1 ]2 d3 c5 O/ lmain.cpp: In function ‘int add(int, int, int)’:1 K# X4 H3 Y5 e
main.cpp:8:29: error: declaration of C function ‘int add(int, int, int)’ conflicts with
; w# h, m7 t$ V6 k( w- V int add(int a, int b , int c)" h# _! ^7 ]- [, G3 ?7 t4 ]
                             ^: Y3 A. \2 N; x% F  O. `
main.cpp:3:5: error: previous declaration ‘int add(int, int)’ here. b+ M  j% J* B: h7 n' d
int add(int a, int b)
9 b0 L, F( B3 d8 H

6 [4 M0 `) J+ q2 P  A) p
目标名起冲突所以报错。
5、小结:
  • 函数重载是c++对c的一个重要升级
  • 函数重载通过参数列表区分不同的同名函数
  • extern关键字能够实现c和c++的相互调用
  • 编译方式决定符号表中的函数名的最终目标名

    ' H3 |' j# ~3 y% j. W
四、总结:
# B) }1 s0 o0 F+ F
+ Q" [$ ~- H  C$ [6 B
好了,今天的分享就到这里,如果文章中有错误或者不理解的地方,可以交流互动,一起进步。

; F/ B7 _- y4 S$ q
赞 收藏 评论0 发布时间:2020-8-10 22:17

举报

0个回答

所属标签

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