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

C++——类型转换函数

[复制链接]
gaosmile 发布时间:2020-8-29 23:30

一、转换构造函数的学习:

1、回忆数据类型转换:

在平时写代码的时候,最怕的就是那种隐式数据类型转换了,一不小心,软件就bug不断;而显式数据类型(一般是程序自己去强制类型转换,这个是我们能够明显的识别和掌控的)。为此我们这里总结了一副隐式类型转换的图:

微信图片_20200829233028.png

下面我们来几个隐式转换的例子:

代码版本一:

#include <iostream>
2 p- }3 X* i9 t; [" N' @#include <string>  y5 r- F5 S7 F1 ^7 L% M
) R; ~8 ~4 H; s: s! A  W
int main()
  O0 T) w: S. O- V7 h  `{# K' p! g' X/ D5 L, |) v2 B5 d
     short s ='a';2 Q6 ?9 j) T# X0 Q  I, C8 {  B
     unsigned int ui = 100;
6 C8 W. K/ T" c     int i = -200;
9 Z# h8 t. v# z8 J     double d = i;
6 Q) T3 f7 Y6 C$ ?3 t1 `7 T& S  @7 j" l: L0 [% U/ A
     std::cout<<"d =" << d <<std::endl;1 ]2 ~& H6 M) H; `2 {, ?! v/ X
     std::cout<<"ui= "<<ui<<std::endl;9 S9 x4 A2 g% N5 R% \, d1 c
& L$ e7 x5 n; [0 q' W: a
     if((ui+i)>0)- M( l* U3 M  r" }. U
     {
, v3 e  }' `$ a) s          std::cout<<"ostive"<<std::endl;, A$ X  y' l( b6 g, `% p" l
     }
, `& x% e4 x- `; n* T9 g     else+ x9 y8 }- ^8 @' o( C9 Z9 n1 |& V
     {' t! V7 A3 l' f0 I( a/ L& `
        std::cout<<"Negative"<<std::endl;
8 t! F. z1 P0 j% M- n3 s     }
" X" k0 f4 M+ J" d' T0 N& ~% d" B& n) J0 U& o
     return 0;5 N& f5 r) p$ T
}
# w2 {3 w8 {$ ?' M9 A( J
0 ^; E% ~3 H: I

输出结果:

root@txp-virtual-machine:/home/txp# ./a.out
5 N9 W$ R4 N( Y& _) v7 J! ~d =-200, L# q' ]- I: r1 l2 t# B
ui= 100
  H: a3 z) K# ]" J; D& i6 c' VPostive. z% Q  k9 I1 T$ V9 T& {
& f' O2 v2 D, C3 Y

注解:这里我们明显发现(-200+100)还是大于0,这显然不符合正常人的思维了;所以我们仔细分析一下,发现这里肯定是进行了隐式转换了,为此我们再加一条语句看看(ui+i)的值到底是多少:

代码版本二:

#include <iostream>& p& P: |2 Z. A, O; C; V
#include <string>
! K0 b7 E) i- u$ Z0 ~; T" s: G
& h- H- ?" f& B8 A/ cint main()
6 W9 o# }7 }0 `# y{( \  f+ n: U. M
     short s ='a';
' K( H/ h" V. }2 E2 I3 _. v     unsigned int ui = 100;
. q1 K! D( c+ U% e- i6 }% y- X! O     int i = -200;
. O0 p% I2 J$ L, p7 f     double d = i;
( l6 }7 G+ P* b/ P$ p2 ]% d  b1 x- ~+ F+ y4 _# Q
     std::cout<<"d =" << d <<std::endl;4 t3 i6 T% E* v% s9 E) I7 a
     std::cout<<"ui= "<<ui<<std::endl;
( B% f: d  F1 |, z+ H7 O2 e: q, r; y4 N3 A$ V7 H
     if((ui+i)>0)
. u  T; O* Q$ Y! q     {
1 d& `, Z2 t& F) @1 G  x        std::cout<<"(ui+i) = "<<ui+i<<std::endl;0 E, z) r: h& l. f2 B# V
        std::cout<<"ostive"<<std::endl;
% N0 k* a1 e  n/ \4 |6 K     }+ m8 _7 y5 V- [
     else
% x# r0 Q; O) N8 q4 J7 k. {     {% G" A0 i! t# z8 H3 S% U/ x6 V
        std::cout<<"Negative"<<std::endl;6 k+ w% v' q  r# t
     }
' L7 x1 ^) t' o. \  A( [- \0 H" M( l0 e3 W8 M' Y
     return 0;
  \0 B3 F4 X8 e- n! R9 j* I}; d$ x! y/ L& l5 Y" |
! f5 @* w  x! K6 C/ o$ H  C6 Q

输出结果:

root@txp-virtual-machine:/home/txp# ./a.out
3 p7 e1 I& u7 j5 Yd =-200
; [5 O! K9 e# J2 eui= 100
- E  }0 Q+ w0 g+ f(ui+i) = 4294967196
6 d$ v: o+ p0 g+ DPostive
9 j) l1 j4 R/ o' c1 @

注解:通过打印(ui+i)的值我们发现,i原本是int数据类型,这里隐式转换成无符号的数据类型了

为了让大家更加理解隐式的转换,我们下面再来一个例子:

代码版本三:

#include <iostream>
$ @# l7 T  r6 t+ h#include <string>) Q6 T) M' a  i$ b

) X* w) ~# s9 E7 L( hint main()+ G+ D+ K) j7 H. g* m8 i( ^
{6 @/ N$ ~7 @* s& P8 K# j" }3 m
     short s ='a';
, v! S! J7 F  k' }/ s( @" W2 I     unsigned int ui = 100;
% r% `$ M5 P) l$ a     int i = -200;3 s# m2 Q8 |( E0 q
     double d = i;
" s; `, p6 l, u, L- u% f6 D6 O$ f) ?. L  M" M8 _, t
     std::cout<<"d =" << d <<std::endl;: n# |; ?0 [; F8 q1 N
     std::cout<<"ui= "<<ui<<std::endl;
+ y8 x( [* H1 G! w, w
) U& d' [+ e. x* M     if((ui+i)>0)4 B. y' _, H; E
     {% r: i# O; Q% i$ `( ]
        std::cout<<"(ui+i) = "<<ui+i<<std::endl;* d& X7 V1 Q" b- T# }8 E
        std::cout<<"ostive"<<std::endl;3 y9 B; k, ?) J" H/ y, h
     }! B' h0 j# t6 u5 f. Y" P
     else1 Y- o! q& u0 a  I
     {4 e: X1 \5 P  w) w8 B! h
        std::cout<<"Negative"<<std::endl;
6 u; M. t7 a0 ?& R' a# ^( q     }
! C) Y1 u* [: Q: ]/ D5 Y- L5 K3 p$ [& M) h5 R5 b# Y
     std::cout<<"sizeof(s+'b') = "<<sizeof(s+'b')<<std::endl;+ f# ~3 ~7 w! H4 W  h$ f8 h! _

: W& G( @! `" i" X9 R2 [     return 0;
, _) }( v4 b0 T% `}5 d2 }" c1 Y# e3 u4 \+ j
# Z% G+ D; x4 E/ {8 Y% _1 |  n

输出结果:

root@txp-virtual-machine:/home/txp# g++ test.cpp
$ n/ b& }4 Q1 q) P) ]! q. n; e. Proot@txp-virtual-machine:/home/txp# ./a.out; N( ]0 H5 b0 n  u" D5 A
d =-200
$ C- O( t0 l& `' s5 fui= 100, ?& x8 X4 D% a. J& ^# X! n5 b
(ui+i) = 4294967196% z& Q2 E' C/ @- a  E4 ~0 u# l! w
Postive
1 H" u" E$ i. ^sizeof(s+'b') = 4) T: m, |3 p* R; S) G. l* N  w; w" u
+ `! M7 y5 V" ]" c

注解:这里我们发现sizeof出来的内存大小是4个字节大小;其实这里编译器把short和char类型的都转换int类型了,所以最终两个int数据相加,所占的内存大小就是int类型了。

所以咋们平时在写代码的时候,脑袋里面要有这种写代码谨慎的思维,防止出现这种隐式转换的情况出现,养成写代码的好习惯

2、普通类型与类类型之间能否进行类型转换,类类型之间又是否能够类型转换呢?

为了说明这些问题,咋们通过实际的代码测试来看看啥情况:

代码:普通类型转换成类类型

#include <iostream>
" U) E) z/ j& P) i#include <string>% n) `4 @9 _7 |! Z2 F( l0 B
1 n; {: V' Q1 f; z8 A& _& @( }
class Test{
8 W6 R: ~7 W- j: S7 y% r
+ d! H2 z& m& N3 Mpublic:
9 ?. a1 I! ]0 \- A    Test()
8 \0 P2 u. N+ l3 D) h, k    {$ w+ ^( ~% x3 d( U$ i8 Q! }5 y
6 L; {9 \2 I8 `& [( P
    }
- x$ n, q$ a/ w; a( }: {! X    Test(int i)
5 W3 u" o* ]/ }+ d    {: {8 }- b/ ?- }1 C

# z& S5 t! p" _- t- \" X# C# }    }5 r( y$ Z3 p# K0 U
};
6 H( z" U, w1 J3 M8 S9 W! `; Y0 |4 Y" \7 n
int main()  g, r5 e6 X9 Q( a9 \
{
" P6 P" ]/ E; |: K, e& G     Test t;+ X; Z; v* I8 d2 E: a5 X

0 o; o1 ?0 i# L. ^1 l- J     t =6; 从 C 语言角度,这里将 5 强制类型转换到 Test 类型,只不过编译器 在这里做了隐式类型转换7 k6 M0 m9 l: w! r8 b' @  `
( Z/ x& j% I4 V1 d  ?
     return 0;
- J9 a; E6 s# W# c! O) B) b6 }6 w}
1 m) H- W- _/ }: p* C: R$ ]( C& p; i$ o: F- A9 \- J3 s/ }

输出结果(显示可以编译通过)

root@txp-virtual-machine:/home/txp# g++ test.cpp& y) o" M* ~! G+ Y
root@txp-virtual-machine:/home/txp# ./a.out8 g& t) L& D& Y" n- m
% I3 C4 W) w% S) I/ {: `2 r

代码类类型转换为普通类型

#include <iostream>. x" M; q+ m, X5 y% c3 u1 r. P* P
#include <string>
4 X1 @, w6 m+ q- [' h
# e/ c; Z. ?8 r( V; @4 X/ @  p& p5 gclass Test{
: p4 q) @$ O2 @7 R; O2 X  P9 r
6 _( B. ^% Q# g) G7 S% cpublic:
/ i* o& Q# D5 P! d3 K4 Z    Test(); K$ d, A4 f! Q4 j2 ?" `
    {7 t) W5 {1 n( i
/ v' Y& X9 S6 A* G3 f/ N
    }
& f% `3 E# n8 y4 R% Y# [+ |    Test(int i)
% V1 H) T9 [, d    {9 W9 D5 s7 G3 P' `

# u  @2 A1 D8 O/ k6 q    }( p) J: h" ^% n4 \
};
. L& H. P8 z* P' {8 j8 a+ c+ J' c6 j) l* e, \8 `/ `8 s/ t; N
int main()6 z* g0 V% a5 S5 t9 A/ ]+ b5 m! w
{
; `2 \9 s6 N' z# }$ K7 q     Test t;
5 x. x* _+ O7 m: ^0 A$ K/ w) E; k2 F/ i0 K9 U! ^
     int i = t;
+ ^* g5 l7 V! ~6 N- q
9 a* U4 o$ E5 L5 E9 v! E     return 0;9 U! L$ \- C5 y! x, e  A- r
}2 U9 ~* D. f2 P% z3 O
. r& M& T3 n3 Q" v  N$ \( X. P2 I

输出结果(没有编译通过)

root@txp-virtual-machine:/home/txp# g++ test.cpp
# Q0 T3 K; d; L% [. Ytest.cpp: In function ‘int main()’:3 M8 N+ I1 u& O+ G5 A
test.cpp:21:14: error: cannot convert ‘Test’ to ‘int’ in initialization7 B+ m5 @7 D" B# z  I
      int i = t;7 j- @+ O6 U! e( y8 n
              ^, {# ]  d! {( G% Y* H8 e& b# x
9 {  g' ?/ d1 }5 n% K' |

代码类类型与类类型之间的转换:

#include <iostream>0 R7 F# r; Y+ A8 n+ S0 a8 I
#include <string>) t3 Z  m9 i$ q0 Q5 M! w  o! b
2 e  O9 V& @' [8 l7 Q
class Value{/ [& D5 t2 }4 ]3 I  s

' \$ `8 x5 o9 G! }+ x- A$ D};( w% B8 f. _( p$ f
. O9 J5 S6 `, `3 l. E# I1 x1 Y
: r. S8 M2 e, z2 I6 U
class Test{: T/ w+ B# T3 b: u$ [/ }/ |  X

' E3 j" c. U, O" Gpublic:
) [9 ]' B/ Y* G. W. e    Test()
4 I' J: J- ]1 ?, p0 M9 X' [    {4 T- y6 |4 F# L  Q0 x, Z& B1 x+ x

& K, D+ H( X" i* r$ s2 R6 l) {3 ?    }! z. I6 ]8 ~3 A+ v1 U/ {) e" F  m- M
    Test(int i)9 T6 v; z& E9 t# n* }6 v+ x
    {% F; l: k) V6 [9 B1 ~' }
( N( L1 M, F6 d7 C% P# K& t: ]  D
    }
( a' i& Y0 t1 W6 [. E: e};2 o) L7 Z2 t3 p# U5 @

7 y8 k) h9 m" h, i8 Jint main()# s. p/ Y! h& n0 C. O
{3 N4 F: Q5 }1 p9 v* C; r% t
     Test t;+ U. l2 S) C& z  ]: g
     Value i;2 T6 m. q$ P- ~) ^
* V+ I) l/ I5 O8 r. T: r
     t=i;* a$ ]2 D3 m" V1 I1 |5 E
( }' r3 [8 O' [5 k1 i: l$ Y
     return 0;5 n, F$ `3 c, H; f5 k
}
6 C% A% w$ n$ N, u3 c( ?4 X; g4 U0 V6 O. l4 a

输出结果(暂时还是不行,编译不通过):

root@txp-virtual-machine:/home/txp# g++ test.cpp: f/ O0 T# x4 d4 P' J
test.cpp: In function ‘int main()’:# c3 v" q7 H& T: |
test.cpp:27:7: error: no match for ‘operator=’ (operand types are ‘Test’ and ‘Value’)+ C7 x% t5 z5 f; F% ?
      t=i;
) v) w( E' k0 H5 i2 w9 [7 ?       ^
6 _3 e$ b$ e$ o- o. stest.cpp:27:7: note: candidate is:3 C7 z: q. w9 I
test.cpp:9:7: note: Test& Test:perator=(const Test&)
! o6 j- D' C2 a2 K/ ?9 W( `# A% g1 w class Test{- T7 m% R. W! ^) o) w5 \
       ^/ l8 j* b0 w. ]
test.cpp:9:7: note:   no known conversion for argument 1 from ‘Value’ to ‘const Test&’6 L' D3 ^$ P* _7 z: U- L

1 t2 j  h1 K# T* R

说明:上面的例子,我们只是简单的按照实际角度出发,发现确实有写转换行不通。那么真理到底是怎样的?我们接着往下看

3、转换构造函数出厂:

我们前面学习过构造函数,构造函数它可以定义不同类型的参数;但是我们今天这里所说的转换构造函数的定义时这样的:

  • 有且仅有一个参数

  • 参数是基本类型

  • 参数是其它类型

    ! A+ ]# o! N! C, M( S9 L6 K/ D

接着我们对上面的普通数据类型转换类类型的代码进行分析:

#include <iostream>( P, y& f! ?2 a# e. V! ^
#include <string>: A8 E7 M! _8 |
' @1 i$ Z6 l9 [
class Test{
5 J$ x) }4 T4 @- {. P6 Z9 ]9 S; K' d, v* w/ ^3 Z
public:
* y. L) C' o* V    Test()
6 V4 j  A' k8 d+ T7 I# d    {
8 Q* I; F3 p9 q! {0 k4 G: F- n0 Z/ w6 u* _
    }0 f& ?6 h8 c' a/ M9 e) \
    Test(int i)
# @1 d2 A& Z: q/ ?- \/ F5 g    {: C9 u  J  l2 d

  u. V1 x" v; Q" r! B7 T    }* G) ?7 W7 R, U( K! S
};& L# q7 d5 ^( y$ t4 Y$ w, V: m! O8 L
( \$ z3 J' R% ^- v! C* D' ]* ^
int main()  k0 L7 S: `( r; ?  B
{
% I/ Z7 M1 l. Y9 [     Test t;
+ b% E. s$ {& R. O  `$ P* u/ o$ [$ V( k* {' S% a3 g
     t =6; //从 C 语言角度,这里将 5 强制类型转换到 Test 类型,只不过编译器 在这里做了隐式类型转换5 Z, ?5 \6 `: y1 x  u# \
0 }. d8 S3 S4 w
     return 0;
; n7 }$ Y- O0 s' z- i" i9 P}
" V  x/ |  _' P

分析:

上面的Test(int i )就是一个转换构造函数,所以我们上面的这句隐式转换语句:

t =6" q* x5 |' x# U  Z: T( V% W

这里其实发生了我们刚才说的利用了转换构造函数,把6转换成Test(6),而这样写就会产生一临时对象,所以就可以进行赋值了;但是在现在的技术发展中,肯定是不希望出现这种要人去防止这隐式转换,所以在c++中有了新技术来防止出现隐式转换:

  • 工程中通过explicit关键字杜绝编译器的转换尝试

  • 转换构造函数被explicit修饰只能进行显示转换(也就是强制类型转换)


    . @: F+ q( n* U6 f1 c! J

代码实践一:

#include <iostream>
7 J' |9 q$ \6 N8 d( F$ H#include <string>" O$ Q( ], l7 `- Q2 K. i  X% F1 Z

% I8 r. k; B3 s3 U  Q' Mclass Test{/ L7 e: y. e! B# W
2 Q7 u& w% k+ m" v  \+ K
public:
! P9 H! j5 D. O& [% d) A+ Z    Test()+ Z: u9 X- f6 i& h+ W
    {) S; l; S# @! V7 R8 V- z: S0 u" A
8 c" h8 H% w# Q' j/ A& m5 E
    }; [: M3 U2 w* O" p; Y9 U
   explicit Test(int i)
1 _4 D1 _% J8 k, m; T" X    {
' {! z0 g0 h, W
& Z; b7 \- B7 {8 m$ f- M: ?  Z1 e    }
( D9 Q) S0 V+ k};/ M- Y  V& _1 F  N
: @( r' O8 V* F. v
int main()
; Q8 i( x4 o7 V( W6 R$ T% r{
8 D) J) ~  t2 f7 s4 |     Test t;9 M/ @" \7 B# I/ J" y! h
" l# r" G7 m/ n, E: F
     t =6;$ f2 b" \$ B! a" p2 g% U

. Z- v: n1 \4 p0 m# F; A( v4 ?( Q     return 0;4 ^9 Q/ O, Z0 ]- I6 ~! x; t
}3 \6 Y# S. y+ u9 v5 e

# d6 Z4 ?% C1 d5 |

输出结果:

root@txp-virtual-machine:/home/txp# g++ test.cpp
( i$ W. O4 o- \" x% T% l5 ztest.cpp: In function ‘int main()’:9 m" e- d* \% Q! p! N
test.cpp:21:8: error: no match for ‘operator=’ (operand types are ‘Test’ and ‘int’)0 P  S: ^1 y; C: T/ z9 l% M
      t =6;
: @) R9 }7 R, z* t" V: |' S7 g        ^
1 r6 `, G  W6 P$ h0 Utest.cpp:21:8: note: candidate is:" o: S' a9 r" L7 L
test.cpp:4:7: note: Test& Test:perator=(const Test&)( c5 W0 h( H# w; G
class Test{
: B% j8 K% I. I       ^
9 [5 l+ {! Z  w0 s, F" H  a7 k0 Itest.cpp:4:7: note:   no known conversion for argument 1 from ‘int’ to ‘const Test&’
0 {3 r& u) [* v- g7 {4 @% t+ @; V9 t3 e3 O; q2 ?$ _

注解:这里显示不能这样转换

代码实践二(进行显示转换):

#include <iostream>
0 ~2 p- S' u/ K, x+ a#include <string>
" i+ S8 f) V5 j- b" I1 S$ {+ M; G; W( q* F4 q$ F
class Test{
8 s9 c0 K  {1 `% K( J" L7 E% x6 T3 {* l( a. o
public:
2 j0 W* s' H% ^    Test()
6 H+ k% Y$ d8 W    {
3 q( p/ w0 r+ E3 o" i. N" X$ ]' L; n  m& t8 j1 J& _1 v
    }7 }& Q+ I) {% c/ }" x9 ~- f0 Y
   explicit Test(int i). Y. W1 \( t, H3 b
    {
0 t, h( V4 y6 Q2 v7 Q) N3 E7 S, j& l5 t( ~* R  V
    }
9 g6 g) p5 r* v( d1 G4 w6 P5 d};+ }. j3 p  Z0 b) e5 Y. N% }

5 j3 E+ r% k) x  p0 V! }# j1 _/ s; T4 ]int main()5 R+ |; x. y; z' Q  R" N$ ~& A
{
9 ~0 K5 ^, ?% G9 j1 Y0 R" x$ o     Test t;) e4 @: R  n% f' e/ l2 p6 ~
1 y9 d; ^: l1 Q9 c: Y0 _9 \
     t =static_cast<Test>(6);5 h4 S! F0 y, F! ?% c
     return 0;
# ~+ o) j) y0 K/ |0 r0 \}
' H" v; j% S" v( y5 E' \: F) |
0 o! T3 R& j( X% z* s# t

输出结果(编译通过):

root@txp-virtual-machine:/home/txp# g++ test.cpp
+ Z& X' q6 q. s3 g  kroot@txp-virtual-machine:/home/txp#
: q- Q0 I+ h( l1 c" N* t! V

4、小结:

  • 转换构造函数只有一个参数

  • 转换构造函数的参数类型是其它类型

  • 转换构造函数在类型转换时被调用

  • 隐式类型转换是工程中bug的重要来源

  • explicit关键字用于杜绝隐式类型转换


    / h" Q3 X8 y9 p! _0 `0 g

二、类型转换函数:

1、类类型转换普通类型:

在我们上面通过代码测试发现不行,那么是真的不行吗,事实是可以进行转换的,不过要用到我们现在c++里面的类型转换函数(它用于将类对象转换为其它类型),类型转换的语法如下:

operator Type()9 p) w8 D- M: l
{# E7 Y- R2 T  F+ h
    Type ret;
8 v4 g5 G4 k, X2 j     6 Y: b4 @1 \8 j- L. b4 _
    return ret;1 E8 V- A7 a& S7 a
% U3 _! ^+ c9 K. w/ o: \- d1 q/ o0 _) H
}3 F9 Z1 E, P1 u& H

代码实践:

#include <iostream>, o7 p/ `9 C, }( b4 y# x, V
#include <string>$ z8 u! _+ h; @+ o4 p

4 o# K4 Q* t0 |6 h0 ]) V- qclass Test{
. G% I8 z+ g" `& x  m, w; G/ b9 f7 L/ E0 }. B! l
public:6 X9 e" w1 y4 h( V3 n0 a
    Test()
. Y# K* c* b  n9 z1 W$ y( Q    {
7 _$ |0 o# H4 D* z& a. {" o
; m: E( ^5 L; S% T2 @# g& l# c    }* x  V5 s; `9 Q& Q* f: b- h1 B
   operator int()
+ S  M# J' q7 j5 m  f3 B   {5 k0 I( C, `* X5 m3 m1 Y5 p7 k
% g8 n8 d' ]0 o5 s# W* b
    }
8 D7 F, e" `( U- }6 H7 o};
# k  e9 @+ n, ?3 Q7 q
' w# P5 a: L$ T6 u7 b: m. Fint main()
8 [2 S3 s2 y! b( x{( j) o# T4 h% B+ g4 T  k4 b
     Test t;
% A4 U( B0 z) u' g6 B" {     int i =t;
2 D" f4 Y2 \/ q6 d- P" P
! @: Y5 A; [4 @% q7 L6 z     return 0;
2 N) R# J3 W3 `- [9 f* o. c}
+ }# v( H6 T5 V8 J. a) ?
: F% w; k+ p% Q7 ?

输出结果(编译没有报错):

root@txp-virtual-machine:/home/txp# g++ test.cpp
/ ~. V  X6 X' Q, Z% {0 ?. yroot@txp-virtual-machine:/home/txp#
8 Y6 N8 x/ i% W, e
! T4 p  _* H5 P) [7 H7 a) ^
5 i8 I  d1 K6 f& G  r

注:

  • 与转换构造函数具有同等的地位

  • 使得编译器有能力将对象转化为其它类型

  • 编译器能够隐式的使用类型转换函数

    6 r! ]3 J. h+ D; D3 Z6 t5 A

2、类类型之间的转换:

这个问题也是之前我们上面简单的测试,不能进行类类型之间的转换;现在我们学习了类型转换函数,是可以进行转换的:

代码版本一:

#include <iostream>$ b. X( s$ d, ]7 l% s' M
#include <string>* o3 B0 @+ Z! _# @7 V9 o
3 V* j# ]& K6 K) R: p
using namespace std;
' [9 c# r9 L0 I; K! g* b# q8 X9 t- Y/ a2 R
class Test;
+ N: U- l) l1 _! x8 H
6 c5 V% a' \9 tclass Value
( A, {% C8 @' q8 {% v5 i* P{6 `* {$ }/ {* G; }; L
public:
2 [, d, |- f/ O, g    Value()
3 y7 }" I( k6 E    {
$ }* Z* \5 F% z; I- [    }5 k. Y7 j/ R5 ]* T: {
    explicit Value(Test& t)
9 r1 r& x$ g& Y8 j0 b7 D' C    {0 N* T& B) K; T
    }
5 e4 m& k/ O/ z, x" k};
  ], Y" \1 l& u2 F
# v" c8 d9 p7 m5 Iclass Test
( n0 P  C) g$ f5 C! T{. k1 K7 e7 f$ A# h; V
    int mValue;: v; g2 X+ U1 U5 A+ U1 I4 i
public:6 c% u# z& j. u; b, Y, N+ I
    Test(int i = 0)( g5 Z7 o+ a9 \
    {& p% Z) v7 F/ n5 w- m
        mValue = i;
* f- ]! I; ?- e/ I    }# a. A& {, u" W' b5 b* e4 ~$ l
    int value()
" k- u1 w3 }0 t$ m$ g, n$ W    {2 s; z/ n, D9 {( z
        return mValue;5 v& o; x$ _8 L
    }
; @6 O5 f- W' B* x  Y! c    operator Value()% D" m: |( g) g5 C& Z, A- L
    {
2 G- h* C' T7 R+ H# n- g        Value ret;. S4 x! p* D: ^
        cout << "operator Value()" << endl;
( K. I- g2 F' w5 r$ p2 ]        return ret;
: T5 m  r+ [" E: c4 p. K" `" n    }8 U; M6 Q- F% [1 e+ X# G/ @
/*工程上通过以下方式;7 K1 E7 b* T. _. B' N! Q; \, ?
  Value toValue()
! P+ @& j2 t4 ~7 ^  {
2 {. Z8 a8 m  r* Q      Value ret;5 e+ d' H; h& g+ Y# J
       & L6 M) i, Z. [, s0 \4 _2 \  V" ?
      return ret;5 L( k9 k4 k. l  C
  
1 R5 y- Q& Q/ Z% i; r8 [  }
& s2 n4 X8 L6 q3 s1 L$ @};
6 D# X+ J: k5 g2 ?  f# a
4 ?/ w3 {! e' |- M& x2 `int main()7 x% F. t$ \: m2 s
{   4 g& I+ j2 X, A" B0 O
    Test t(100);
( m% l* p: E2 m/ R2 Q5 O# i    Value v = t;
% v- X( N- G# H4 ~9 `$ N# B3 g2 [   
% z0 h2 m, C, o    return 0;9 O1 L  x4 E0 ^  c. P% b
}
% M7 \$ U, |) i+ e" K2 c$ ^3 G. T; ~0 w( N

输出结果(编译通过):

root@txp-virtual-machine:/home/txp# g++ test.cpp% y- X. `/ F6 R$ a2 b: r8 K
root@txp-virtual-machine:/home/txp# . z0 k( q* j) u

' l0 d  h* F% g- k' S$ _6 m  I) Y2 g. U1 E7 q6 [7 @+ ?

注意:这里还有一种让编译器犯难的转换写法;我们上面这样写是用explicit关键字屏蔽了Value类里面的隐式转换,所以不会犯难,下面是犯难的代码示例:

#include <iostream>1 A! ]- f; K3 ~1 x
#include <string>
' Z- S" ~4 `8 G6 @* R% T# n, r
! n4 w+ f/ V* @1 W5 ausing namespace std;4 j4 h4 m7 U& E# C9 ]

% ^7 ~9 ^$ R% F5 N8 A- O1 d0 t1 C! fclass Test;9 T, T  `+ W* i0 m1 Z
* n: E2 D: `7 N
class Value
" q  _8 h! V- H6 {{
. a" z& w& H9 L  p: s" m1 opublic:- F/ d% @% C) J6 M1 `; s( V
    Value()' o* b$ V$ |; r* _
    {
$ c; c. z. e8 Q$ }7 \$ P    }
% Z3 v" e# u$ T  _9 B3 m  {     Value(Test& t)
/ m4 k$ E6 L, q) X0 N+ }% S    {
3 l0 {  q* }; i8 @. x% H& A+ a* s0 X    }
, C; q, N% W( R% _) L};/ u. u* W+ v4 d- }/ S
+ K0 A1 w$ a. w$ m6 |
class Test# M: A: r) s1 S3 n
{+ Q8 |5 H  R" _, Z5 ~  o' {
    int mValue;
; t/ Z) y# k' n/ ^public:+ o5 U  a/ t# G
    Test(int i = 0)5 R# t% V7 F+ [& e4 \- w& A
    {
. w3 ~) ]0 e. J, {- D        mValue = i;+ [) I: u+ @7 G' e2 i
    }
/ G4 U/ V/ O( T0 c2 b    int value()4 T2 e. S' l& c9 a5 o: C+ k
    {
6 n; ~5 i& v2 f4 G( u8 }        return mValue;
! @7 K( |) D1 |" d+ z    }
2 ~3 S; P9 c6 [$ s6 O" a5 c    operator Value()
" C/ R) h: e% @) [! j) v2 ?% {    {
! \2 n) m% ^& l4 I% K% n        Value ret;
9 l, @8 u9 M* A1 a4 n        cout << "operator Value()" << endl;
. W& c3 A9 q, j9 j: H! q% e3 }/ a        return ret;
  C1 g# I1 r& }# N7 Z  ^- x6 j: S    }
! v" {8 K$ N9 }7 @( V# C9 ?* F};
9 M3 o& e6 s: M; t' U* X' y* p& ^& l6 s
int main()# S- p' j  X2 i! a2 h
{   2 a; [4 p4 X  h; c5 D9 n% o8 x
    Test t(100);
7 b0 s$ Y/ [# ~1 i6 F: _    Value v = t;
% q6 U5 z. \/ P- F; K- ^% w% S    & r* w3 ]6 ^0 C3 O8 A3 r  l
    return 0;/ T: r# E, n( V! K+ X% Y
}
/ K( N4 C; j( W" r' e% y
$ [6 X9 j9 B7 X& o5 K7 M/ P

输出结果:

root@txp-virtual-machine:/home/txp# g++ test.cpp
8 I! l6 c6 o6 O" e8 k7 _test.cpp: In function ‘int main()’:
: X9 v: ~9 m# Y7 ttest.cpp:42:15: error: conversion from ‘Test’ to ‘Value’ is ambiguous
$ p7 Q4 H5 e8 G8 I" N+ Q$ ~     Value v = t;
& o8 e( d' Q7 O3 W               ^
+ }- d/ U$ v7 a; x+ Y. Dtest.cpp:41:10: note: candidates are:& E9 e4 ?- Q) g
     Test t(100);- K8 g. r$ A$ C# N; H- {$ X4 [
          ^
$ K: }$ @, T0 R- Z; ~+ \test.cpp:31:5: note: Test:perator Value()
+ c7 A# Y5 q) m* o$ @) m  S     operator Value()
9 M1 _! w0 C8 ^$ u1 F7 z/ O( c     ^
* v9 G" N! Q% i" a1 G1 utest.cpp:14:6: note: Value::Value(Test&)
6 D& }1 C3 d, D$ d: \2 L! g      Value(Test& t)
$ _; M% }8 n- }& c* O) U+ S9 Z! J& p' b! z. R/ I0 D

3、小结:

  • 无法抑制隐式的类型转换函数调用

  • 类型转换函数可能与转换构造函数起冲突

  • 当然工程中可能比较习惯用 Type toType()的公有成员代替类型转换函数(就是换了种写法)

    * D! _0 M3 K6 X& d2 Y9 U

好了,今天的分享就到这里,如果文章中有错误或者不理解的地方,可以交流互动,一起进步。

/ T9 q- h% D" R2 _: Y5 P
赞 收藏 评论0 发布时间:2020-8-29 23:30

举报

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