7 F; ^! G# ?6 V& X假设有一幅RGB图像720*576个像素,每个像素有RGB三个通道,每个通道的值是8bit大小。给出图像的首地址p_rgb_image, 我们要取第40行,第50个像素的R,G,B值。代码如下: # x$ P- ]& E+ x2 x' n/ |: Y! a5 |9 Y9 H) ~
unsigned char* p_rgb_image; 5 v0 m: [( q, s& j3 {unsigned char r = p_rgb_image[40*720*3 + 50 + 0]; ) ^" A/ X, M2 Y8 l j! b( |3 Cunsigned char g = p_rgb_image[40*720*3 + 50 + 1]; 5 U7 Z' W) Y7 N& @* S, V9 y4 q: n( [unsigned char b = p_rgb_image[40*720*3 + 50 + 2]; p/ @+ o( T7 y s o
类似这样的场景, 采用多维数组的写法, 有点类似以索引为参数,可读性更高。相当于程序员和编译器打了一个配合。 3 t( j3 ?/ {, s9 }5 K# }+ K! g# W, A' A8 I' ?. D! [
enum5 e2 o; l6 o) p& _ B
{ ; {6 z! q+ g9 K# Q Red = 0,9 s J/ T* [- a- J Q: \# ~
Green = 1, # v2 s+ e/ d1 F% Y, } Blue = 2% u4 |* x n# ]$ l9 A# P p8 s9 K
};5 U$ w+ ]. h+ X) Z4 L. h$ t
unsigned char rgb_image[576][720][3]; j# C- i* e9 z/ v4 J5 [6 F7 e2 f7 xint row = 40; m3 p; e& t& J* g% \* wint col = 50;( F9 @! u j7 V, V
unsigned char r = rgb_image[row][col][Red]; + e$ ^. J0 R3 [2 Vunsigned char g = rgb_image[row][col][Green];+ I; ]+ W: E5 v0 y5 g' b# [- ^
unsigned char b = rgb_image[row][col][Blue]; ' ~6 L3 ?0 D' j+ M数组指针以及与指针数组的区别 $ q4 \" L5 d! T! S+ H c: }9 a8 d2 `. u数组指针,是一个指针, 指向的对象是数组。 数组指针的赋值,要求数组的长度匹配,否则会报错。当指向1维数组时, 需用用*取得数组对象的引用,再用下标来访问数组元素。 % I* Z# _# C' Q1 e' m, d ~指针数组,是一个数组, 数组保存的元素的类型是指针。 4 ]/ `( u; Q% z5 S数组指针的定义& l3 g+ s; Y" x2 T
数组指针定义先定义一个数组。 3 c% g7 w( t5 H; Z5 z6 U5 n. G; Mint a[10];! N/ O- R! i2 ]6 I
然后对数组里的名称用括号括起来后再在变量名称前面加个*号& h4 N g1 J. v) a
int (*a)[10];1 S4 M, q( D$ x0 r" e( O
后面你会发现函数指针定义类似。 0 s# _2 [1 Z' \% k+ C// 各类定义对比 9 {7 x' [0 |) b9 A: ^$ c: mint a, *b, **c, d[10], e[10][20], *f[10], (*g)[10], *(*h)[10];- z& L0 o% V' d; D
* F% J- B0 W: Z; Q Dint *f[10]; // 指针数组, f是包含10个元素的数组, 数组里每一个元素的类型都是int** A2 X2 ^6 y D* P
int *(f2[10]); // 指针数组。另外一种定义方式。 & ?/ K2 d2 k; B: vint(*f3[10]); // 指针数组。另外一种定义方式。 $ {4 }) v P5 l7 q% Xint(f4)[10]; // int数组 6 d0 _; S' ~, h# bint(*g)[10]; // 数组指针, g是一个指针, 这个指针可以指向类型是int,元素个数是10的数组0 w( F, c5 p" d) v. y
int* (*h)[10]; // 数组指针, h是一个指针, 这个指针可以指向类型是int*,元素个数是10的指针数组7 r6 l, S- r; Y7 A. l" `9 `
* \0 ~: O, d1 j5 X4 X: q$ r
int d[10];, T! z8 o* d5 [5 r5 `( x2 R7 S
g = &d; , Y5 r6 l- u0 H% {; n8 o8 a( P/ o: ~2 @9 P
int* e[10];6 }8 }& c' }+ |0 y
h = &e; 0 z5 O8 w: \9 d7 v8 [) v! C数组指针的使用2 z6 i# p7 |; `' e; \
数组指针一般先通过*号取得指针指向的数组对象, 然后再用下标操作访问元素。9 _: ~3 t2 u- W' |
/ q! C" o! w! ]3 tint a[10]; , x% R. Q" I9 R% ~8 Q' H g% oint(*p_ary)[10] = &a; // p_ary是一个指针, 指向"int (*)[10]"类型的数组* s2 ?/ S& s' f
for (int i = 0; i < 10; i++) { 2 i* B4 n9 d5 k1 _% q6 U // p_ary是一个指向数组的指针, 需要先通过间接寻址运算符*(indirection operator)取得数组对象" F( X( I& J( l# i' h( E" ]
// 再通过下标操作访问元素。 & ~1 y! |7 \9 Z$ |% ` u' N (*p_ary) = i; ! U! x. m) {) J7 Z6 T4 Z! P} 4 S$ A; s# f' H8 s8 o1 O3 W3 }6 d+ O( {. J$ Z1 Y' b# k. r
int b[10];! x x2 w2 B; J( h: r# X
int c[20]; & M0 y# ^. d1 f8 b& T# r! ep_ary = &b; // 合法0 |5 F/ _8 i5 C
p_ary = &c; // 报错! 不能将 "int (*)[20]" 类型的值分配到 "int (*)[10]" 类型的实体4 q& T" x/ k: D
数组指针指向多维数组的子数组 2 X8 r$ Y5 I5 ^% Lint a[10];, V+ Z* d$ E$ D
int b[4][10];9 R* i9 h$ ^9 d9 g4 y
int(*p_ary)[10] = &a;5 C: Z$ ?$ n/ M; @
for (int i = 0; i < 10; i++) {+ M) v* g$ B3 N; Y
(*p_ary) = 1; % @1 n; m& F& Z4 G) ~} - e% Z- ?) W* v( j1 H, k: b$ ?( J, f+ J; V9 F v
p_ary = &b[2]; // 多维数组,可以看作数组的数组,) ~* \, L, a9 Y. k
// b[2][0] ~ b[2][9]的值都被改成2了6 r4 H6 ?( O8 C' r y: B
for (int i = 0; i < 10; i++) {! \1 U$ b; @) T6 L# W( Z
(*p_ary) = 2; & Q A) W4 Z: N4 j0 O# U}9 I* v: @8 I7 u$ X) z3 V
多维数组指针 * Q$ z1 ^$ Y6 v5 A3 Z0 }多维数组指针,是一种指针,指向的对象是个多维数组,支持多个下标操作。7 s0 b, p3 \4 e8 z$ F
: V$ a1 P# u3 _
int a[2][5][10];, [/ q7 l/ Q+ q# R
int(*p_ary1)[10] = &a[1][2]; // 1维数组指针 & ]7 E! ?( V" i, h, }) S1 |* N" pint(*p_ary2)[5][10] = &a[1]; // 2维数组指针; Z$ E, @' K8 v1 ?% Z
for (int row = 0; row < 5; row++) {7 L. D0 u; e/ m n7 V' s
for (int col = 0; col < 10; col++) { * `* Y4 ~! b" u8 ]% ]7 Q" T, m (*p_ary2)[row][col] = row * col; / ~9 p9 h4 I$ d+ S- w* m } . O* G# k" ^$ \! `5 A2 ~}, x a- g, k+ H; V( m8 i+ s- h, `/ _
数组指针和指针数组对比实例2 p9 S/ r7 _2 x6 ]3 W( g5 Q
数组指针还是记住两步法即可: ~: p: i. _' w K% \* z
: I# T1 d- A' h2 l: H( a. N0 Y5 W6 v定义一个数组 # L( O+ d: ^/ j, e" w# x) O括号包围1中定义的名称,再在名称前加个*号。; U# d, |( m; Y# _
int a[10]; 7 F3 {* H5 T3 h, v3 N6 N; [# ^int(*ary_pointer1)[10] = &a; // 数组指针4 |: E8 I H& t3 G
int* pointer_ary1[10]; // 指针数组。元素类型是int*3 K1 q. e5 l. h$ ]) t z' w1 d+ B
int *(ponter_ary2[10]); // 指针数组。另外一种定义方式。 ' M6 b1 y5 b' `, X/ E% q. nint (*ponter_ary3[10]); // 指针数组。另外一种定义方式。4 J- e1 r5 p6 d7 j& X3 J' Z0 w7 S
int c, *d, (*ary_pointer2)[10], *pointer_ary3[10]; // 排列定义比较。5 a( G4 b! f8 j0 O8 g; i
! x. [! O. |7 B2 h' Y/ z
// 指针数组可以把每个元素指向数组对应位置的地址。; R4 ]8 e0 ]2 s+ s5 W! E; {
// 这样遍历指针数组, 可以达到遍历数组元素的效果,但是注意每个元素都是指针, ) h, Y$ @ }5 X2 ~! r' n// 需要访问原数组的值的话, 需要对指针用*间接寻址运算符。 . u/ Z% c6 A2 S- S# {4 sint* pointer_ary[10]; : [! V% } O9 y5 ]5 I$ Efor (int i = 0; i < 10; i++) {: ^/ C0 z* H+ {. _& _* _' [
pointer_ary = &a; , e% t, S: a0 \' o2 W* `} ( }; q2 f7 M7 ~5 T8 k& n3 e// 类似遍历原数组效果。. U4 t8 a k0 P8 z' F- D. O( f
for (int i = 0; i < 10; i++) { 2 S- x8 ]6 ?1 p- s2 w& h# {4 K *pointer_ary = i; // 修改原数组。 : n0 j) z/ z9 N& v1 d, f# }}' u- m3 R8 u3 J C5 Y0 Z- @
( Z, S, D, E) M7 |+ i: c# j# T1 _函数指针 ; o- v) N- H0 M" Q. N( {9 @取得函数地址 E, W2 |9 r& \/ d函数的名称作为参数被传递时,会隐式转换成函数指针, 和在函数名称前加取地址符&等价。建议带上更加统一和清晰。+ E/ _# @0 [! @+ z* [6 d5 q2 Q
3 C- }' C; s3 n* W ~
void f(int);, A/ H4 W; L- p; c" A
int main() - C) z+ z" r8 ?' m- S3 _{- ?/ E9 |$ a _! a
void (*p1)(int) = &f; 0 s9 t1 g, s3 W0 [9 x o3 f void (*p2)(int) = f; // same as &f % i& c: d j% n# F7 M return 0;% n/ l0 R; t! [" U7 L
} " F4 b0 a. U' G u/ J; Q. ^翻译成汇编代码, p1和p2的赋值是一样的。" y5 k1 a! L5 t' z, ]7 H
) L7 T# d+ r1 {" |* }" x; [ 2 I! T4 m- G) ^; N6 v3 c6 S* R+ ^1 \4 ?* Q% N+ z% K
函数指针的声明0 o4 d& |% ]5 i) ?9 p9 l
单个函数指针变量定义步骤 6 E3 p6 Z1 k5 f) r定义一个函数。void fun1(int a, int b); int fun2(double a);3 h6 n" U6 A+ B5 y: `
用括号把函数名称包围起来,然后在名称前面加*号。void (*fun1)(int a, int b); int (*fun2)(double a); " ?" K @ y! J9 e如果要定义函数指针数组,在定义单个函数指针的基础上,在名称后面加上[数组长度]void (*fun1[2])(int a, int b); int (*fun2[10])(double a);9 S0 i' U1 m. V! G1 ^
typedef定义函数指针6 A5 k# x( u D! g" v7 p
可读性高比单个定义要高,特别是声明多个同类型的函数指针,或者函数指针数组。) R3 I7 m* ]; f' _2 n+ W
, \ T) N, S' h$ i3 [
typedef定义函数指针的语法 1 L8 t, K' m& dtypedef有两种做法, 一种就是定义一种函数对象,另外一种就是定义函数指针。用法稍稍不同,效果是一样。其中函数对象不支持赋值, 但是支持引用。 " I/ \# S: O, A9 ?; o1 n, a6 I) A# Q
typedef int FuncObject(int a, int b); // FuncObject类型是函数对象 0 j% d' E! u- d! q. v, Itypedef int (*FuncPointer)(int a, int b); // FuncPointer类型是函数指针$ j/ {; T: z4 i- s
FuncObject* f1 = &Add; 3 g; e$ |! l8 b! Y' S7 U6 T* H; TFuncPointer f2;& `9 p- W* C& T+ G8 t
f2 = f1; // f1, f2类型一样, 都是形式为int(int, int)的函数的指针。 & i* F: {2 M+ dFuncObject f3 = Add; // 报错! 函数对象不支持拷贝 6 G; c+ W8 V2 @" B" V+ L' O- FFuncObject f4 = &Add; // 报错!&Add是函数指针,与函数对象类型不匹配 - C5 m4 m0 b7 iFuncObject& f5 = Add; // 正确4 u2 v; B$ K7 y1 P3 P
int ret = f5(2, 3); // 正确* R4 q4 f& b P; p
FuncObject& f6 = &Add; // 报错!&Add是函数指针,与函数对象引用类型不匹配 + L! v& ?% ]) L: ^如何记住typedef定义函数指针的步骤 * r t- X8 B* F0 P# }像定义一个函数指针那样, 指定一个名称。int (*CalFun)(int a, int b); 5 D3 B6 Y: V6 c' Z2 w1 g/ I在这个函数指针变量声明前面加上typedef。typedef int (*CalFun)(int a, int b); ' T$ a" Z. ?" ^2 ?2 j$ L完整例子 2 O8 S9 A9 f/ p6 @9 dtypedef int(*CalFun)(int a, int b); / v2 g+ e& K1 \. M$ C 1 P; L L9 q8 M0 |- Kint Add(int a, int b) 4 D) ^2 t+ w2 ~6 E- f{ * Q6 w/ O4 f9 ?5 a3 a0 Y7 M' c return (a + b); . f, \4 s4 X4 c, w6 _4 h! L}9 e- |8 E! x# _% u. G7 ^$ N& u8 m7 @
8 x5 b/ N; X* n. S* i4 L. K
int Sub(int a, int b) 6 D: y1 T5 ~& _# E" Z3 F' f8 q{6 B; c1 X3 }/ h" W8 e
return (a - b);+ `# R, ^; i- k: o- S
} % \! m/ m5 A! E8 f3 S 4 J4 C0 z! ]* j6 g' U2 V( E+ wint main(int argc, char** argv) 8 T3 W; E8 @1 i* |{+ i% D7 W L' Y" s' o9 X
CalFun f1 = Add; 7 V0 L- {) ~' y* n( y CalFun f2 = Sub; 2 A3 `7 c" k8 M! ~; j, V8 ~6 Z int a = f1(2, 3); ( Z! T; n8 s+ }: r2 r+ M int b = f2(10, 5);" Z7 [9 C1 S# C9 z: z6 L0 N: g
" J: q# `' p: ?1 A // typedef定义的函数指针数组。; W( e" ^7 z; d" I
CalFun f_ary[2];( k$ o2 ~: l- M5 w
f_ary[0] = Add;% ?# V0 X4 A/ r" X0 |5 t# n
f_ary[1] = Sub; & G" q% V4 P* l& {5 |: W( `% g7 g$ w# o1 u/ @' B5 @
// 单个定义的函数指针数组。8 n- b: N" E; u
int(*f_ary2[2])(int a, int b); # ?; A4 Q+ @2 Z f_ary2[0] = Add;: G, G+ ?* t( t
f_ary2[1] = Sub; - u9 z1 N6 I ?4 W 4 k5 z6 Q: Q: q, Q: u' s. h7 \9 \ return 0; - B3 i6 j4 V' [3 W- T' w} w- h* r' Z( Z! Z
$ w( T, \$ J+ i* yusing别名定义函数指针 3 V* [- J0 e3 v7 zc++11以后的类型别名定义--using也可以用于定义函数指针, typedef的好处它都有,个人感觉比typedef更直观。using类型别名同样分函数对象和函数指针两种方式。1 @2 s" P1 t2 s; f3 Q! b2 v. [4 O
7 ]1 p- k' ~: v* ^7 e3 m+ V2 [5 G
typedef int FuncObject(int a, int b); // FuncObject类型是函数对象1 c6 X/ K6 y1 H7 m! V- G
using FuncObject = int(int a, int b);9 m! N# _& a; _' y
typedef int (*FuncPointer)(int a, int b); // FuncPointer类型是函数指针 7 x3 `, n* J4 Qusing FuncPointer = int(*)(int a, int b);' k0 m9 V- E! O7 W5 o3 f
函数指针的调用( Y" @$ }7 ~: i0 q) a
函数指针和函数对象都可以直接后加括号调用 6 B7 v0 u. z) V7 [int f();& N; H6 m" ?5 j+ w/ ]
int (*p)() = f; // pointer p is pointing to f , [3 O* T8 C) ?9 Vint (&r)() = *p; // the lvalue that identifies f is bound to a reference2 ~8 P+ Z; o( ^) L. _1 t# U
r(); // function f invoked through lvalue reference k/ C# a. a$ R, \# R! B5 a0 f(*p)(); // function f invoked through the function lvalue$ P$ B, M0 m" ?9 f. d) `7 ]
p(); // function f invoked directly through the pointer) ], ~1 J+ ]1 s# Y- x0 |1 j
如果函数有重载, 函数指针会指向匹配的那个版本。5 ~, ]' K! v. O* r( L
template<typename T> 7 e! S! F2 f9 d C1 @; PT f(T n) { return n; } $ P5 v6 V9 B3 s4 {8 w3 S+ Q+ S, o {5 \ }4 V2 }. V: _( s
double f(double n) { return n; } 4 X1 Q. q; u% m ! X: l: J v8 b( Uint main() , Y, x% L" t" I3 w& S{- _8 _1 [& \ o; f# p
int (*p)(int) = f; // instantiates and selects f<int> 2 l$ t x7 ^% F" }- E) w} ' o( U4 e$ F+ x' g6 j) {. a成员函数指针 + L0 c8 b6 f# H静态成员函数,除了增加了访问控制以外,跟普通的函数指针没什么区别,所以普通函数指针可以直接指向类的静态成员函数。但非静态的成员函数与普通函数指针不太一样,声明时需要指定函数归属的类名,并且调用需要指定对象实例。7 }5 R" z# h& [5 X% g' f
4 X9 C4 R) r, q2 ?成员函数指针定义。$ k6 f3 R6 e9 D$ Y( i2 v
像定义类成员函数实现那样写, 并任意指定名称,这里作func。void ClassName::func(int);3 d, v, G* Y$ r2 N
括号把类名、范围解析运算符::、名称包围起来。void (ClassName::func)(int); 0 P9 |+ Z5 M! R. T. a在名称的前面加个*号void (ClassName::*func)(int);/ b+ i3 ?; b" r
成员函数也支持typedef和using的定义方式。typedef void(C::* MemberFunc)(int); using MemberFunc = void(C::*)(int); 2 G* l, c3 r) ~+ Q7 X# I成员函数指针如何调用。 8 \) W7 {2 Z! u% @假设成员函数指针名字为func/ X* P3 k2 a) P+ ?8 W" y% |1 g
( D7 k4 G4 K: p ]% u) t Tvoid (ClassName::*func)(int); 6 w5 m8 W4 u0 v. e: u/ n' t对象式调用。( E" Q5 W$ J2 n+ Q- G7 n
ClassName c; // 被调用的对象 : \% g1 ]( Y: G. d成员函数指针名字当作正常函数那样写。 o% E8 H/ _. l8 O" W2 C4 h0 @' qc.func(3);/ i' t8 ^4 ^% Z! d8 y" Q
成员函数指针是指针, func名称前面需加上间接寻址运算符*,变成函数对象。 q, K( w' v, G0 O* q7 L6 N
c.*func(3);, c$ F n2 n* k1 R
最后用括号把调用对象、成员访问运算符.、间接寻址运算符*、和成员函数指针的名称包围起来。 ; P' K9 t# P" Q* ?' x* }5 w(c.*func)(3); $ Z3 y9 K# q) K7 T1 _! Z3 @为何要加上括号? 根据c++的优先级标准,取成员运算符. > 函数调用() > 间接引用符*。 *号优先级比函数调用要低, 成员函数指针还没取得对象就被调用了,自然报错。 另外! r( } z. {' ~
(c.(*func))(3); / m8 I. y/ Z$ `这样的写法也不行。 .*和->*是整体作为一个运算符的,中间不能用括号隔开。0 F- j9 t2 D) v. g+ p( \$ L! Y4 \# g
指针式调用) M6 l$ x) h; b: h+ D0 f
ClassName* p; // 被调用的对象的指针. p* _. b( `& ?, M
成员函数指针名字当作正常函数那样写。* r- C5 C, F1 `' k$ a j1 Q; K" Q
p->func(3); 6 m- X) E! M* C1 }/ j6 ~2 W, X) O) x成员函数指针是指针, func名称前面需加上间接寻址运算符*,变成函数对象。 2 H4 F! y) O; _p->*func(3);. g+ D8 `: [$ o( S# l: T
最后用括号把调用对象、成员访问运算符->、间接寻址运算符*、和成员函数指针的名称包围起来。 R1 {, }- f5 @& `(p->*func)(3); : h+ P# a i7 X, T# v; `# _函数指针使用完整例子 ( J" ^+ r; O4 D. n* u1 lstruct Cal , ~0 t' F8 }# g; H; G3 ]. f{ + G! {& U7 Y4 s+ [7 z int add(int a, int b); 7 s* b4 `7 W8 @5 r. q" b, Z! ^8 z1 ? int sub(int a, int b);0 p9 K) u. h/ O& R5 V3 l
};* p# t ?/ F8 q
& T5 r6 K5 n" [/ Y0 J0 J" t: W) Q- |int main() 8 V5 |3 s+ l2 x/ ^' x; @{ - `' Z. H/ }% |+ r) i! w- p o int (Cal::*fun)(int, int) = &Cal::add; ' | r0 i- K8 t# R# o8 O fun = &Cal::sub;6 `! G8 x" g# \' z9 \
9 U! ?& U! z; m* e7 j0 l4 Q Cal* p_cal = new Cal(); 8 C- l9 R E0 Q1 G int r1 = (p_cal->*fun)(2, 3);: n- q$ B# J4 {) ^7 T9 M
delete p_cal;1 R2 a1 j, s" K9 c7 E) P4 H2 p
4 j! ?, R8 |9 V% ~4 }3 o Cal local_cal; $ B7 Q7 Y) X5 X# j4 V int r2 = (local_cal.*fun)(8, 6); 5 o5 r) x y0 Z6 Y4 `7 J}# K g1 ^1 G! f7 N* s7 R- |& b
1 ]1 f, @7 [* B. [8 I6 j2 R成员变量指针- i6 z: C+ V/ K" z% C+ W
成员变量指针比成员函数指针还要简单些,没有函数调用, 无需考虑函数调用和间接引用符*的优先级问题。 2 D9 ?0 ]& ?5 _6 A- f. T: J3 C5 i; s( Z K
成员变量指针的定义 ( `+ V/ u S6 ]假如以下结构体C。/ T9 a* ?& X- W& H# D* L
: O1 W7 k2 B' V3 K0 v; O# _$ Sstruct C ) U8 c1 h/ ~% I0 r{ , F2 X# g' S9 ?& H int m; ; ^5 l; o: Y. V* W6 `: Z
};& S/ }, U/ e% y. |/ F
单个成员变量指针定义 7 [4 p A" E9 a3 b- Q, P; w
假设名称为p, 类似静态成员变量定义那样声明1 }5 C" p& T$ m. Y7 ]( l# Q4 q% i
int C::p; : H4 G; }* X) D% G在名称前面加上指针标识号* 7 j0 u, f$ ?2 s( g( \* S6 l
int C::*p; + a! f; D1 e7 w) O" btypedef或using方式定义, Y6 h; b+ F8 T
typedef int C::*MemberPointer; 3 Q/ p9 Z2 G: ?. f' Musing MemberPointer = int C::*; 4 U' q# V1 C. g o t9 \成员变量指针的使用。! m2 I% S; m0 Q
类似成员函数指针那样,直接使用指向成员的指针运算符:.* 和->*即可。 1 [6 c% V5 N% ~7 V成员变量指针, 能让我们实现一些遍历成员的动态功能。 例如把一个类/结构体的多个同类型的成员变量放进一个容器里,然后遍历访问这些成员变量。8 W# T% z& p/ L; Y% g
+ l% o. W% }3 e! F* u 完整例子 F4 k! _% a0 r* q& q' W/ F
struct C { int m; };+ J# j8 e# V4 Y
int main() u$ a* d) Q" o1 U{8 v/ R1 m4 i8 d" R9 ?% d8 l
int C::* p = &C::m; // pointer to data member m of class C / w% r H3 Y( p7 U Y8 }8 q C c = {7};" g- r( h. z9 P; Y
std::cout << c.*p << '\n'; // prints 74 a) U! O4 Q! N8 J1 h
C* cp = &c;' f% ]' ^4 ]$ g! K9 L
cp->m = 10; 8 p- M0 x/ p; V9 D std::cout << cp->*p << '\n'; // prints 10 / y; X$ J; U" ~8 J3 Q, M" i1 P % i/ L2 ~) S5 ]8 _% X————————————————: `- g: v f9 q2 I( ~, g9 R
版权声明:本文为CSDN博主「南风fahaxiki」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 ) {0 T- _6 Z, ]0 O) Q+ a ?原文链接:https://blog.csdn.net/m0_64407685/article/details/126788115 H( H3 _% Y* V; ~