C++ 关于类的那些基础事

上一篇 / 下一篇  2012-03-28 09:31:53 / 个人分类:C++

(一)类的const成员函数与重载

7`&^@v$j![0N0  1、看看下面的代码,定义了一个dispaly()和重载了一个display();我们现在聊聊const函数成员和,const重载。我们知道将函数成员的后面加上const是定义一个const函数成员。那么const函数成员有什么特性呢?

)bp]1DZ#T/SO0 51Testing软件测试网&hT+k-FL j

  很简单就是不能改变其所操作的数据成员。其实还有一个作用哦,就是实现重载函数。需要注意的是在display()重载成员函数并不是前面的cosnt在起着作用哦,因为我们是不能依靠返回值的类型不同来实现函数的重载的。这条想必大家都是知道的。

1U+a0_j.Fu0 51Testing软件测试网J\TErP/kxbJ6W

51Testing软件测试网x*ke:| w9pL;rl3`

#include<iostream>
M2Ci TP*H.J7V0using namespace std;51Testing软件测试网6ud]` b;oG
class Screen{51Testing软件测试网iD+bW1{"})]kx
private:51Testing软件测试网ee6A8W c$]#N
 void do_display() const51Testing软件测试网O:I"fZ[-{
 {
IfcL]%a*`6Z0  cout<<"OK!!!"<<endl;
/zMXO R-k$S0 }51Testing软件测试网 w2p4B*bB YKX#j
public:
k0i3P w*kd_|r f0 Screen &display()
0L2l;Gdy M;}0 {
Z8Ym7{/pd;S0  cout<<"Not const."<<endl;51Testing软件测试网.P-DP0Lk&j'?S
  do_display();
(J(iK.ok7h m'P%]0  return *this;
*f!p#iT}!T2}0 }
/H W]t D+{z$Y v0 const Screen &display()const
}#Fk.{tI$W(RA'a0 {51Testing软件测试网 zgLsYp
  cout<<"Const."<<endl;
r(G"xys]!i6o0  do_display();51Testing软件测试网/[G)Z+f4C/\@
  return *this;
g"RU?Q0 }51Testing软件测试网'}.r&^\5mOb
};51Testing软件测试网1f6e3E+r$Z
int main()
(yx AG+l#H0{
2rE%X{xW2S%Wl0 Screen screen;51Testing软件测试网 y~cs$x
 screen.display();51Testing软件测试网p&[X1k7i4X%~Y
 const Screen screen1;
]l1y-XJX~0 screen1.display();
Mw rfSwR/L/k;w0 return 0;
F(K-]*{4aE)m K0}
51Testing软件测试网 ?)i5Ij[J(y]E

9v|;~4o F@:Luw%a-m0

0Ms/eA7l1t0  不信你可以试试,将后面的const去掉改成下面这样:

B{2d]D.BF0 51Testing软件测试网.DH9h9}:e jv

51Testing软件测试网Me)g&_/n D

const Screen &display()
c*jM8D$}?_0{
O[%h:HT0 cout<<"Const."<<endl;51Testing软件测试网*` Q4EX TH"Ivy
 do_display();51Testing软件测试网&u5Ws+CTs c
 return *this;51Testing软件测试网8nsm#Kq
}

]:z;PsIF-A0

!x0w W.`b O9V0

(Z[@b'kq0  编译器将会报错告诉你无法重载仅按返回值类型重载的函数。还有一点需要注意的就是const成员必须在定义和声明中都出现哦。51Testing软件测试网B[[D @c.wv

5chK0Nl/nb0  2、注意区分返回*this中的this是一个指向类类型的const指针和指向const类类型的const的指针51Testing软件测试网S3@}B7k-R8b1kx7?

51Testing软件测试网S7S1HNb _)X U }

  指向类类型的const指针是指可以改变this所指向的值,但是不能改变this所保存的地址。而指向const类类型的const的指针,既不能改变this所指向的地址,也不能改变所指向的对象。或许你还是不明白吧。其实this可定是指向一个地址,这是没有什么质疑的吧。const指针也就是说这个地址是const的,所以this所指向的地址是不可变。也就是说,无论你现在所向的对象是谁?但是总是存放在这块内存中。而const类类型的对象,显然就是说对象是const的,对象的是不能改变的,自然对象里面的值也是不能改变的。那么指向const类类型的const指针就是指向某一固定的内存的某一固定的对象,地址和对象都不能改变。

+[ `#a{Ner0 51Testing软件测试网s&u3s~x*Z Y:Dd

  上面的例子中开始的函数返回的是指向类类型的const指针,重载的函数display()则返回的是指向const类类型的const的指针。后者是不能在改变所指向的对象的。51Testing软件测试网cNE2v|h\

C;[+si(xF3m4@Z@0(二)返回值类型不一定在类的作用域中

5S%L KoY8Y6d+[0

#P&xv3{#h a Fb0  观察线面代码:51Testing软件测试网+P0}P;sO7`)t

+[}9|klw8U0

!P7z'K*c7A \0

~:CQW;t'N4[\8?!G i:P0

.XtYd` ?0} Z0class A{51Testing软件测试网!riu!}&[8t X
public:
6]5? G5aer&e0 typedef string::size_type type;51Testing软件测试网4S9x#wIr%{4EN,I
 type getCur() const;
7a/j-j&k5kR0private:
2^-k yjjz~0 type cur;
T5L]1Cq0};
yw|9bY}K8L0type A::getCur() const51Testing软件测试网r8z@y C*]C;B

51Testing软件测试网.T @"b&G E6I4m"i Z"qQ

51Testing软件测试网%i*_.Du I
{51Testing软件测试网6e&l.W6cHAF E H
 return cur;51Testing软件测试网fJ2\*~S4K$Yn
}51Testing软件测试网\w!LeSUw

51Testing软件测试网Itk+D"wOn m

51Testing软件测试网N6Xmy!l6dhh1}

51Testing软件测试网 V"lA3J }1ssb~$L

Y4~+f/t(B"f0  我们知道typedef的几个基本用处:51Testing软件测试网)K \6Di7?0U}

HP+v2Ok D}l#RW0  (1)隐藏特定的类型实现,强调使用类型的目的。51Testing软件测试网1{7} u$D6HT-}zqJ6V

51Testing软件测试网x2j bbdl!\A

  (2)简化复杂的类型的定义,使其更易理解。

z @;{.s5N#]m$d jN0 51Testing软件测试网F-?3]&Gq}]g(|

  (3)允许一种类型多种用途。51Testing软件测试网#?re5_3XyI

]]|9{%G-S\~iuu3GP C0  我们在此处使用的就是(2)简化复杂类型的定义。对于(3)的应用,学过windows程序设计的人,应该不陌生。(1)的应用估计大家用的都比较多吧!51Testing软件测试网%Qvv _-v(Aw;eQ

y s ~-on V|0  很明显的是你会编译不通过,因为type是一个在类里面定义的类型。在定义体之外定义就要注意了哦;要改成

Zrt9CW&G%?0

&Cg.jO!]Hj0

:q/lwLKR;R0 51Testing软件测试网#n^s2T6l

A::typeA::getCur() const
51Testing软件测试网$c0Yj&PP"~

8}-^ s*m3\ WF0

!Vi:d*v|:L0 51Testing软件测试网,|3C0c|.['jE7Q8n4y

  关于构造函数51Testing软件测试网:La!E+xu

51Testing软件测试网D9IaX[zV

  关于构造函数,大家应该都十分熟悉了吧,几天和大家一起看看一些需要注意的地方。51Testing软件测试网 _`-X7i p;u:_0B

E@1_ DU9|V#s0  1、必须注意的是有些成员必须用初始化列表实现初始化。51Testing软件测试网(b+kQ ]2V.c:cw

exS[\3JT}0  (1)没有构造函数的类类型成员。51Testing软件测试网+N!H[^8I

51Testing软件测试网/_6\:wsD@,[ B

  (2)const成员或引用类型成员

S/J._G'g"\7j0

#X kQkC6Lo$u0  首先解释一下(2)吧。我们知道对于const和引用类型的对象是只能初始化而不能做对他们赋值的。所以自然就只能用初始化列表了哦。

9p0S0|ueg0D0 51Testing软件测试网ala5X+X]

  对于(1)的解释,看看下面的代码吧。

e*Nn(y[9@0 51Testing软件测试网 ?\7Gf-M%P*n8~Z

51Testing软件测试网-_K pUXj4VB

`d0M } \*DUZ0

#include<iostream>
!nJ:P Fu*lF!["o0using namespace std;51Testing软件测试网6@]7vQ'lF Z3c
class A{51Testing软件测试网 ij W-v`Lr\7?
private:51Testing软件测试网Y&o)`"|(O guv
 int cur;
J6F:[:w ~'}3si0public:
:bT4I&uZ8v)I0 A(int cur)51Testing软件测试网A@7WHSn
 {
'{ yV`A/Fq0  this->cur = cur;51Testing软件测试网Y!ZEPTs l8eoase
 }
YY0]1Y'l"V2[ g"e0};
7hVQ[9`^0//A没有默认的构造函数,所以在B的默认构造函数中,只能用初始化列表来实现51Testing软件测试网NR2i$W.q)m ~F;?%c:u
class B{
m"g6F"V _EG0private:51Testing软件测试网3N?&eg`HN|
 A a;
+Zd#k4F+nF(Wo0public:51Testing软件测试网$pR:`O&j6tm
 B():a(10)51Testing软件测试网Rs%Q R?,E:ZiK\rs'U
 {51Testing软件测试网9LC!p#Od$CCZ
 }51Testing软件测试网7yD2swG!fS*^b
};51Testing软件测试网)y7yhK_
想想你如果不是用的初始化列表,那么你可就没有办法初始化咯!!!所以类总是声明和定义默认构造函数是个不错的选择。

j_u&V2u0 51Testing软件测试网]!g Z+Sj?6BY

2、默认构造函数,你只要记住下面这句话就OK了。

:[ p;T\7w E0 51Testing软件测试网Y+L-wr&`3Z0Zj8JI3W,S5k

  如果一个类哪怕只定义了一个构造函数编译器在也不会生成默认构造函数。51Testing软件测试网0T1J9Va2]&E;P4a VIC

51Testing软件测试网K]KuhrS T6{,p

  关于默认构造函数可以参看下面这篇博文:C/C++--C++默认参数及其所引起的二义性51Testing软件测试网|f+_9v t%w

M!a1r$~;q3P0Dc0  (三)隐式类类型转换

)v)zm!PFpB0 51Testing软件测试网m2A8@7QIO

  看看下面的代码吧:51Testing软件测试网k%c Mz"Z

51Testing软件测试网{!_;wae,? i W[

wyH6h"C;A9h0

\|;eK%TH1g0

#include<string>
aE dk;Lv&^%e0#include<iostream>51Testing软件测试网rN R JXA)BY
using namespace std;
#s`+~9hvV5O'm"Y0class Same{
/?qZ9c1zb5l.s5D0private:51Testing软件测试网.v[@ GUP,Jek
 string isbn;51Testing软件测试网;i6R%d1rx;}
public:51Testing软件测试网*p;[e:K;J l g
 Same(const string &book = ""):isbn(book)51Testing软件测试网0j'o[PP#a
 {51Testing软件测试网*jle^D h3K
  cout<<"Same() is run!!!"<<endl;
}'F*wr*S _Hk4[.]~0 }
6_&h8rjjm0 bool is_same(const Same s1)51Testing软件测试网._ w3F\;W0N@BT'u
 {
6[d$E4pO6H/V0nr0  return isbn>s1.isbn;
{`&z:WBL0 }51Testing软件测试网kp{(c ?2W7F
};
}P/{,g*caj0// 应该用explict消除这种,隐式的类型转换。而用显示的类型转换;
^A!?!L;@nQ:}0//以免产生语义上的错误.
rj B(d&A[KD*r_0int main()51Testing软件测试网af6A:fbmV
{51Testing软件测试网4p n9_+mq6S'G
 string nullBook = "Head First";51Testing软件测试网d^zO+Z
 Same same;51Testing软件测试网"_!L7[,m.vWb2K8P
 cout<<(same.is_same(nullBook)? "True":"False")<<endl;
,RO5UutK4z%i3c0 return 0;51Testing软件测试网,J+B6g5}V6TE Z
}
51Testing软件测试网'r"? Z5X#XT-V+Z#L'pH

51Testing软件测试网QX?"Hkl k4X

51Testing软件测试网1y _8iT+^ t6k0aU

Q5\:YP V4EF0  注意在is_same(constSame s1);调用的时候就有一个隐式的类型转换,直接将string隐式的通过调用构造函数,生成了一个临时的Same对象。运行你会发现,Same()调用了两次哦。51Testing软件测试网0jo}?R,I*M`;e2m([

xW/iW n y^ U| s0  不过这可不是什么好习惯哦。对于这样的隐式类型转换有时候是让人匪夷所思的。所以最好就是使用explict声明,使其不会产生隐式类型的转换。而是用现实的构造函数的调用来实现:same.is_same(Same(bullBook))这样意图就很明显了吧。51Testing软件测试网9uF `q;?"H&x


TAG:

 

评分:0

我来说两句

Open Toolbar