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

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

(一)类的const成员函数与重载 51Testing软件测试网7I3GEgY

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

7T/i1Z#n#_Z,@8p-e ~0

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

q ?p$pb,t,n^*y0 51Testing软件测试网b-U*Wr sm3U

8m} FfOicL%\f0
#include<iostream>
5f yVB*I!Clx&nd0using namespace std;51Testing软件测试网vH6F)s M ~-hXA
class Screen{51Testing软件测试网g L*W9Z.O9Q-XuAt
private:
D:ARD ku0 void do_display() const
,@z(CT _#b0tg7C v0 {51Testing软件测试网']&ICs/x-w,b(IP/C a
  cout<<"OK!!!"<<endl;
C$e'J(LrE&b,V0r"d I0 }51Testing软件测试网h0O H"bp5S2q-K'K
public:51Testing软件测试网,e`Y#m&x+rx$U c
 Screen &display()51Testing软件测试网-B H vN`yk
 {
hY#@(j$P F`;e%@0  cout<<"Not const."<<endl;51Testing软件测试网@b}1K/bA#[$~-I p5Rr
  do_display();
.Z6`3fCe"UUn0  return *this;51Testing软件测试网&xs0p4\-cD/R
 }51Testing软件测试网;} }8ko&S/ioO _
 const Screen &display()const
'i'R+_"G8nLml0 {51Testing软件测试网/C[m ~\)]
  cout<<"Const."<<endl;
U c$p)U6`+N/G5sL0  do_display();
vc e&W#j9T0  return *this;
*e:r,K:`5p$p&|w f%T9E?r\0 }51Testing软件测试网-Uzh6pg3}
};
?N5n9DNI0int main()51Testing软件测试网 g.HX S0mY
{51Testing软件测试网*UD o E4P_Q5j+P%a0iZ
 Screen screen;
vwFVt*\,U^.E'u0 screen.display();51Testing软件测试网;S,D4A |ia\ O
 const Screen screen1;
N+B"y i7n0 screen1.display();
do"cj3up M0 return 0;
T(I XTpM5q W#]|0}
51Testing软件测试网0i9pD"JapXM

51Testing软件测试网 G ^t5b*jP2{J

DtQ H5K4\VXh_0  不信你可以试试,将后面的const去掉改成下面这样:

,~(VA|I/`Ct8I0 51Testing软件测试网j-g D R~j.l0Ad

51Testing软件测试网/? H!E.[5y1Z*nw9z

const Screen &display()51Testing软件测试网8ky@_9Z
{51Testing软件测试网'm%{6R:b-A(c0]
 cout<<"Const."<<endl;51Testing软件测试网yR ?#i3jp:~
 do_display();
$Ch | C;D4zX0 return *this;51Testing软件测试网l3Td*JFzL%X'z/U
}
51Testing软件测试网3EgC4QT4\.C

51Testing软件测试网3c,\Puc5v

51Testing软件测试网L7\c^q&C

  编译器将会报错告诉你无法重载仅按返回值类型重载的函数。还有一点需要注意的就是const成员必须在定义和声明中都出现哦。

ZR!yn Y'R0 51Testing软件测试网 Q!U9wt Zt zOj

  2、注意区分返回*this中的this是一个指向类类型的const指针和指向const类类型的const的指针

J xv:h[Q0 51Testing软件测试网6n-j,O R1e)f5yc.OU#QN

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

:~1U&^5m&B q0 51Testing软件测试网3`i7K){x

  上面的例子中开始的函数返回的是指向类类型的const指针,重载的函数display()则返回的是指向const类类型的const的指针。后者是不能在改变所指向的对象的。

7RV"{m4d^0 51Testing软件测试网 y)^] H"L{+N

(二)返回值类型不一定在类的作用域中

%V:[6h4qf0 51Testing软件测试网7O+H:p3?$Zeg;[f#a

  观察线面代码:

Z(L,`-w-^0 51Testing软件测试网OI5o,OHD1yO1l

9MeWF?y-]W0

/\I~y;A8k$C&Nd0

51Testing软件测试网{] i I.OKm'|

class A{51Testing软件测试网#DSC.Sm4U
public:51Testing软件测试网3a a*@yD9uB-S
 typedef string::size_type type;
-N+OUI2X9C[*R#Vu^0 type getCur() const;
kXS4siGt3x,g0private:
\e7F4FM\@.gn1J0 type cur;51Testing软件测试网+bk*X2A2A6|+PX`
};51Testing软件测试网-_j$T-IQ
type A::getCur() const

7a D+m1k Cw/_0 51Testing软件测试网hD~2_P"Yxr ?


9zZQ;B&I ]&S'QM_0{
"ULg)Hi~_A0 return cur;51Testing软件测试网Sd(YD*Dk"a
}

Bf EJ z*B/ms%X#O0
51Testing软件测试网ieFN4c

51Testing软件测试网,Uw3Te5D@d

:ENgv)D:gPyM0

6gaF|2N4Pk\}2g0  我们知道typedef的几个基本用处:51Testing软件测试网(C |*g%N1I

`i2M[\(mn8vS(WH}0  (1)隐藏特定的类型实现,强调使用类型的目的。

Qy i\vL$tA-k0 51Testing软件测试网vzn2o'e;l

  (2)简化复杂的类型的定义,使其更易理解。51Testing软件测试网 }(T+Hk_

51Testing软件测试网%N E;?!I#sy6Cn

  (3)允许一种类型多种用途。51Testing软件测试网9h+o;h$kq-B

51Testing软件测试网.vm3ygw

  我们在此处使用的就是(2)简化复杂类型的定义。对于(3)的应用,学过windows程序设计的人,应该不陌生。(1)的应用估计大家用的都比较多吧!

i5j+X1e1eW0I)y0

(Q&u1y(a-MrB }I0  很明显的是你会编译不通过,因为type是一个在类里面定义的类型。在定义体之外定义就要注意了哦;要改成

(d {)OVE Q.Wq K0

e\3M&\9{O'Mo051Testing软件测试网|z0z5t(lr%?c

vC)Kd2WF-V0

A::typeA::getCur() const

EM(am!k+l4\!cp%A'x0 51Testing软件测试网%r w*_?p|W__4q

eG;`y&}"^0 51Testing软件测试网9blv-K@m,c;`eL

  关于构造函数51Testing软件测试网5m'_-o ["dr,|Ys

Qi'b.BL0  关于构造函数,大家应该都十分熟悉了吧,几天和大家一起看看一些需要注意的地方。51Testing软件测试网7?a(`#sn

51Testing软件测试网7v/o;B/t |V}:K

  1、必须注意的是有些成员必须用初始化列表实现初始化。51Testing软件测试网}TaF1dOZ t;nK e@x

'K%j;@/jG Cd*jg0  (1)没有构造函数的类类型成员。51Testing软件测试网&O m!k i ZU

51Testing软件测试网3E:aK:u\C X.o

  (2)const成员或引用类型成员51Testing软件测试网"m.Lv"\ds g

_9l9Zi2P*u0  首先解释一下(2)吧。我们知道对于const和引用类型的对象是只能初始化而不能做对他们赋值的。所以自然就只能用初始化列表了哦。51Testing软件测试网-w9De*r.q7y

51Testing软件测试网'D B#M|F1l)i

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

s4m5tJgo0 51Testing软件测试网 h7L jW*v;HY7r4T1j

+GR W?6k$H&c z?0

_gqN0olm6?2L0

#include<iostream>51Testing软件测试网+UDW!lA }H
using namespace std;
4`y({8R0ckr d,K@*`0class A{51Testing软件测试网:qe#R+X-I yq"~ JV
private:51Testing软件测试网/_ L0z!MG3tUl2Q#{
 int cur;51Testing软件测试网 {v8DgLj
public:
C+N[M+_0 A(int cur)51Testing软件测试网DFowd
 {51Testing软件测试网9}N4IL.e+o/]J
  this->cur = cur;
)[` uV1p,?`+i0 }
"vhe"kA\5JI0};
M2n ~K8~/]0//A没有默认的构造函数,所以在B的默认构造函数中,只能用初始化列表来实现51Testing软件测试网-I'I3} y8Hz6F*b
class B{
8Wz/O${oP/B*`0private:51Testing软件测试网%A4`C`.Qq.i
 A a;
LZ A(v^c,te6L | k0public:51Testing软件测试网n9DsQ[XG%Yo b
 B():a(10)
nE(u:O!\:NU4}0 {
+_-fd&bG8@-u0 }51Testing软件测试网b&s_ [xb&]HKDm
};
!M!U|)x_:d:dv;_5y'S0想想你如果不是用的初始化列表,那么你可就没有办法初始化咯!!!所以类总是声明和定义默认构造函数是个不错的选择。
51Testing软件测试网i"AS9k3l4e9h

51Testing软件测试网jf5gE5C9V

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

pA;@A%?!i9O*x,h0

Q~#w5O_Y0  如果一个类哪怕只定义了一个构造函数编译器在也不会生成默认构造函数。

P8f7p5I*bBlP0 51Testing软件测试网!o"k m7I J

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

fLW1p6a7Cs0  (三)隐式类类型转换51Testing软件测试网1AuDq)Ss]j

51Testing软件测试网v:iqcl~T

  看看下面的代码吧:

IB f w(@{5J0 51Testing软件测试网.IP)YrraQ\

51Testing软件测试网9?vI/p7F^6LJ

51Testing软件测试网"FPC"m,Lo*^

#include<string>
ZCQ_CJ%Q/f O)f0#include<iostream>
2CMW WM?0using namespace std;
9ul\-u C}/J0class Same{51Testing软件测试网,PVe.W] Y vL9FU
private:
S"y%EL$l0 string isbn;51Testing软件测试网{7h@~`Sl4Tm9G
public:51Testing软件测试网"Y AJJ"?$X K%d
 Same(const string &book = ""):isbn(book)
I I)q@(GYd }e?0 {
k0nxt*tNM0  cout<<"Same() is run!!!"<<endl;51Testing软件测试网;~nXbR8C8{7^7g)g/TH-b
 }51Testing软件测试网-v'G%`AC(a lV}S
 bool is_same(const Same s1)
3sw1AT rP@0 {51Testing软件测试网/x1~N4^g3_)n
  return isbn>s1.isbn;
(mru t r#c mC-^0 }
SGyU g,N#x eg0};51Testing软件测试网Fo'g'[fU
// 应该用explict消除这种,隐式的类型转换。而用显示的类型转换;51Testing软件测试网}7Y.W\s6V/`qgS
//以免产生语义上的错误.
Y'W8z uwL0int main()51Testing软件测试网]@_s,O`-eT
{
*VSw:I ?*T.L#Tl0 string nullBook = "Head First";
2bOn!H? {B-E0 Same same;
#k5~jD7}0 cout<<(same.is_same(nullBook)? "True":"False")<<endl;
&Kje)a/Q1f\)GR0 return 0;51Testing软件测试网S8s3iYO(E-p
}

:e8f*nzYwhu |Nc2q0 51Testing软件测试网xu|#O2n)s/e

51Testing软件测试网7w%k6V3@ ^6o$YZo&u

51Testing软件测试网8u@ zk e)[8B

  注意在is_same(constSame s1);调用的时候就有一个隐式的类型转换,直接将string隐式的通过调用构造函数,生成了一个临时的Same对象。运行你会发现,Same()调用了两次哦。

._!W1d3c!l-Z7I8_$@,Moa0

8J,T q2Czm-M0  不过这可不是什么好习惯哦。对于这样的隐式类型转换有时候是让人匪夷所思的。所以最好就是使用explict声明,使其不会产生隐式类型的转换。而是用现实的构造函数的调用来实现:same.is_same(Same(bullBook))这样意图就很明显了吧。

~:lnZ"sQ0

TAG:

 

评分:0

我来说两句

Open Toolbar