|
来自:ZDNet
5 j& o* f" d/ F- k3 |* S+ n; l4 UC++会区分两种类型的成员函数:静态成员函数和非静态成员函数。这两者之间的一个重大区别是,静态成员函数不接受隐含的this自变量。所以,它就无法访问自己类的非静态成员。
* v/ h. H9 `9 |, s3 W/ Y# J在某些条件下,比如说在使用诸如pthread(它不支持类)此类的多线程库时,就必须使用静态的成员函数,因为其地址同C语言函数的地址兼容。这种铜限制就迫使程序员要利用各种解决办法才能够从静态成员函数访问到非静态数据成员。 # T+ C I3 b0 [/ b: y
第一个解决办法是声明类的所有数据成员都是静态的。运用这种方式的话,静态的成员函数就能够直接地访问它们,例如:
1 Q% p @, X, D5 m9 Y6 @class Singleton
9 w! e5 \! [& D& n/ v6 b( c9 r1 G{4 U R5 S3 B' o
public:
/ |! A2 I( ? ~# A2 m# Y4 e& `8 L static Singleton * instance();# _/ m% {6 N) w* W6 H& t
private:
' Q7 w' @8 E; t' n Singleton * p;
7 q6 K# |( V6 c8 w static Lock lock;
# r, Y# d9 ^- E};
9 q& a4 o3 B- s5 [
- k$ m+ q ~2 w; t6 M- nSingleton * Singleton::instance()3 a$ _: q7 @5 X
{/ `* H! y% J7 a+ |% T
lock.getlock(); // fine, lock is static
- G3 S+ x: W+ q# u- P if (!p)
& P- s1 w% x# ~1 y p=new Singleton;
" ^6 c$ O. T* F& |$ U! p/ k( z! w- s lock.unlock();
% F% H: {1 d& C' ?( m: m8 g7 E return p;
6 h7 z+ }! B- N' ^2 i% \9 m" s. I} + V. D, a, [" E1 `! G* v( j1 H
这种解决方法不适用于需要使用非静态数据成员的类。
) x+ G3 \* o% o" B访问非静态数据成员 4 X+ L+ g3 L) ~8 i+ b# w
将参照传递给需要考量的对象能够让静态的成员函数访问到对象的非静态数据:
7 ]. T' w2 j8 u2 a" r* E/ wclass A
; a7 f- w6 G7 ~/ ]{6 y. A/ X8 F3 A: T2 a1 s' A
public:
" z/ {; c$ l* _+ Y* o static void func(A & obj);
@/ J5 S9 G( g intgetval() const; //non-static member function- } _0 E" a" d& b
private:
1 T0 Q" N- V, I9 g3 i, w' J) s intval;
( H5 |! `5 E3 y4 Z1 g$ _};
0 v$ ~, Z7 n/ j, C# `静态成员函数func()会使用参照obj来访问非静态成员val。
, V: q. ]9 R+ N; Y0 XvoidA::func(A & obj)4 c! Q, o0 _6 U; P2 m% n& K
{
3 K& u0 Q; \& C9 [ int n = obj.getval();* i- }9 z9 q! J- j; y
} . h* V' i. e0 L: m; l$ ^
将一个参照或者指针作为静态成员函数的自变量传递,就是在模仿自动传递非静态成员函数里this自变量这一行为。 |