0 T3 X1 m3 h, g7 R5 a M) M假设有一幅RGB图像720*576个像素,每个像素有RGB三个通道,每个通道的值是8bit大小。给出图像的首地址p_rgb_image, 我们要取第40行,第50个像素的R,G,B值。代码如下:6 _- {9 ]1 O3 P* Q' a3 ~" X/ G& A
4 \) @( y2 U" [2 ?5 V$ s" M' lunsigned char* p_rgb_image; % ~4 C+ D( q8 a7 M/ v% s* wunsigned char r = p_rgb_image[40*720*3 + 50 + 0];0 T0 K% J- O$ K& I9 F
unsigned char g = p_rgb_image[40*720*3 + 50 + 1];' ], p- w3 y+ v+ {% D/ j
unsigned char b = p_rgb_image[40*720*3 + 50 + 2]; 7 I7 {- r, q" U% S; n8 x类似这样的场景, 采用多维数组的写法, 有点类似以索引为参数,可读性更高。相当于程序员和编译器打了一个配合。& [9 A, F) E- @5 I' P, P( g
% w2 [8 N% s9 W. @
enum 4 o6 b$ Z7 I" @; C0 G7 R2 \ n3 _{8 R% ]+ A0 Z+ g) l! v) r# E7 ^
Red = 0,! p% Z' I0 L3 K+ R( D* O6 [
Green = 1,5 h I) v' P4 Y5 x
Blue = 2 8 `, |( b- ]3 Z" b9 o& ^0 w}; 7 H# R% @9 y$ ^3 |: Ounsigned char rgb_image[576][720][3]; : x* H& h1 L% {" C0 L$ s0 U& Dint row = 40; 1 e; p- O. d" M ]int col = 50;& f! W+ S# V3 w
unsigned char r = rgb_image[row][col][Red];' e# z* ]4 O" }, v; X5 {
unsigned char g = rgb_image[row][col][Green]; 7 W3 p# b: y o$ o8 X% t, punsigned char b = rgb_image[row][col][Blue];# O3 P+ J0 N4 g9 k8 s
数组指针以及与指针数组的区别 % ~' L+ B2 i. i- s- h数组指针,是一个指针, 指向的对象是数组。 数组指针的赋值,要求数组的长度匹配,否则会报错。当指向1维数组时, 需用用*取得数组对象的引用,再用下标来访问数组元素。* |; X$ R% j1 [% l' ]
指针数组,是一个数组, 数组保存的元素的类型是指针。* S& h: N4 P$ a# Q: |' M
数组指针的定义 8 _' [, R" u/ i- ?. a D, d数组指针定义先定义一个数组。3 ?! \4 B# H8 n1 y/ ]; a+ F
int a[10]; ! e$ K! u7 o: |8 G然后对数组里的名称用括号括起来后再在变量名称前面加个*号 ( m& X( ]- ]# X/ Bint (*a)[10];7 f4 f3 C3 T3 R# l
后面你会发现函数指针定义类似。$ N* R/ u- G1 i* l# {2 a
// 各类定义对比; v2 D; Q5 v! `4 j. S' i! R4 g) i$ b
int a, *b, **c, d[10], e[10][20], *f[10], (*g)[10], *(*h)[10]; 5 _* j$ _& t9 y" q8 \1 M7 [$ `# s : f; h v* ?/ wint *f[10]; // 指针数组, f是包含10个元素的数组, 数组里每一个元素的类型都是int* , c- B% D. X5 }1 b4 `6 k1 k+ |5 Lint *(f2[10]); // 指针数组。另外一种定义方式。 , v P, Q. @7 F% G; {9 B: P0 A* F6 |int(*f3[10]); // 指针数组。另外一种定义方式。 n" k1 m5 v6 K2 ]* Fint(f4)[10]; // int数组7 \0 p3 r; n' E9 B& D
int(*g)[10]; // 数组指针, g是一个指针, 这个指针可以指向类型是int,元素个数是10的数组 1 H, M/ F- h- m, g" x$ ]+ oint* (*h)[10]; // 数组指针, h是一个指针, 这个指针可以指向类型是int*,元素个数是10的指针数组 3 e" e$ p" a/ ]$ s9 y/ Z( O4 ^' R( H' f" x/ T! Q' _. H
int d[10]; ; c! A# O H3 Y, _$ t+ d( ?g = &d;+ ^. L- p e7 P( t& [
4 Z v2 N [4 C Y) u1 {% `5 O! m
int* e[10]; 1 o X; e5 T# \( H9 b4 lh = &e; , ]& q! b/ E! N. a3 ]4 v数组指针的使用 2 ?9 ^9 P& S# d! w+ M3 [数组指针一般先通过*号取得指针指向的数组对象, 然后再用下标操作访问元素。8 B v$ f! h8 ]! N
, e* H2 {, A0 o" N% v2 @- q( ]
int a[10]; 0 v9 m: T0 Q+ W- }' h. I( tint(*p_ary)[10] = &a; // p_ary是一个指针, 指向"int (*)[10]"类型的数组" S) d( N& I0 d) }) J
for (int i = 0; i < 10; i++) { 4 X6 {: |2 G( x, y j' g# p // p_ary是一个指向数组的指针, 需要先通过间接寻址运算符*(indirection operator)取得数组对象/ c3 i! j7 s- k7 h! z6 D. w0 E
// 再通过下标操作访问元素。 % R- {) ~) @8 k. e0 | (*p_ary) = i; " f, A6 q2 g6 [. V5 e1 B$ M
}6 V0 i: X9 m, q1 \. U
- v, Z; R# _7 y9 `
int b[10];: Y @3 f' l" f" j
int c[20]; # j& x3 l% o L& ?p_ary = &b; // 合法 & G t( V+ p, I, f/ s9 {p_ary = &c; // 报错! 不能将 "int (*)[20]" 类型的值分配到 "int (*)[10]" 类型的实体 , N3 F: ~! k1 x) n2 W! P: L" q数组指针指向多维数组的子数组# S3 p- ^8 w1 `4 R) u
int a[10];6 S0 K6 d$ t& H, `. Q* t& c/ t
int b[4][10]; 3 G* V( u$ J) d8 C4 V+ I* f" D& L, Gint(*p_ary)[10] = &a; , }: f0 ^$ u3 Y0 }for (int i = 0; i < 10; i++) { # ]7 l6 [ _8 [& a* d% P (*p_ary) = 1; & r: l/ f. a# h5 O# ?# A5 H
} 3 S `3 f- q1 u. \" g% _' S/ i* \
p_ary = &b[2]; // 多维数组,可以看作数组的数组, - O! U r& H. N! ~: J// b[2][0] ~ b[2][9]的值都被改成2了 4 J/ n: t% `+ }2 [. Mfor (int i = 0; i < 10; i++) { $ z- ^1 y0 o! j8 _! j (*p_ary) = 2; % ^+ r' |& W( r' V1 I& ]* s} 7 N' A: F) r, Z% ^( |" R多维数组指针 ( D+ R) x. m; C% x$ Y2 v多维数组指针,是一种指针,指向的对象是个多维数组,支持多个下标操作。 + P% t8 j' Z' U0 [9 E1 } ' {9 H) {" x' B( Q5 kint a[2][5][10];' T( d0 S- [7 E1 i; P. m9 x% Z
int(*p_ary1)[10] = &a[1][2]; // 1维数组指针, U& j' M3 a+ N o- ^, ^
int(*p_ary2)[5][10] = &a[1]; // 2维数组指针- N# {& E2 g* V, v/ M% K) |
for (int row = 0; row < 5; row++) {% k* i5 P" K0 h% \2 D+ S& S
for (int col = 0; col < 10; col++) { ' C) ?) T& k( e (*p_ary2)[row][col] = row * col; - k4 l- m( P; r } , |0 d9 j5 y! m( R: D1 T& U, n7 k}6 u7 d; h" j1 Z/ E6 V
数组指针和指针数组对比实例 + q0 f. L1 x( J9 [( j数组指针还是记住两步法即可- f. P6 q2 v7 \$ s7 O
4 F8 h/ c9 u2 |7 |3 t* O' R定义一个数组5 \9 E- i& i; q, p- g C8 R
括号包围1中定义的名称,再在名称前加个*号。" S7 J+ A& }6 X1 q
int a[10];/ s& ^' R# x( \9 p" p2 j
int(*ary_pointer1)[10] = &a; // 数组指针. e# c8 p/ M( J2 k0 E( R
int* pointer_ary1[10]; // 指针数组。元素类型是int*8 W! _" h0 E( C7 h5 O
int *(ponter_ary2[10]); // 指针数组。另外一种定义方式。 ?( R9 l# I2 F. H/ b* a
int (*ponter_ary3[10]); // 指针数组。另外一种定义方式。 . T" v+ _7 V i& d" sint c, *d, (*ary_pointer2)[10], *pointer_ary3[10]; // 排列定义比较。. N" V0 }$ `& r7 A
- D+ p: w5 Y6 G% K// 指针数组可以把每个元素指向数组对应位置的地址。 ' s2 R y4 U9 `# L2 ^7 I// 这样遍历指针数组, 可以达到遍历数组元素的效果,但是注意每个元素都是指针, , c, d1 r" S( x1 @: J0 D// 需要访问原数组的值的话, 需要对指针用*间接寻址运算符。 7 A) H* K) }. D$ kint* pointer_ary[10]; + m- j5 j9 v4 e# Qfor (int i = 0; i < 10; i++) { ( Q. [8 T8 o5 U+ J& e) D& T pointer_ary = &a; " h* n0 |/ g; D$ G& G. N5 N" q+ O} 8 _ Y. G: H" P1 `& | g. Q0 W// 类似遍历原数组效果。8 ?0 n1 x. u3 ?4 x+ m! Q
for (int i = 0; i < 10; i++) {: ~! g5 |7 f0 ^5 W
*pointer_ary = i; // 修改原数组。 : h6 d- f6 U/ z! f; x2 g3 u$ U} * E: p$ |* g* \7 x- L' S( |2 L ^& i9 d, E8 n6 N
函数指针 0 z( M6 x2 H8 i% u8 j, w取得函数地址 8 `3 F3 l, \! c" y函数的名称作为参数被传递时,会隐式转换成函数指针, 和在函数名称前加取地址符&等价。建议带上更加统一和清晰。 # m. y) G9 a- T" o6 m9 N- c % @ ^) a9 G ?# B6 P6 r1 ovoid f(int); / m! \; u* i% I5 b& B! vint main() 9 |2 C# V: g7 v/ A2 }5 G& Q{. e/ C+ U$ s+ b
void (*p1)(int) = &f; ' S1 R( j9 r1 a' ]9 T void (*p2)(int) = f; // same as &f ' |" ~0 {/ v; [ q return 0;4 T; Q! m+ G0 V. B4 D `( B
}8 S8 @ `' Z" h9 [; D
翻译成汇编代码, p1和p2的赋值是一样的。 6 t, H* W! C. Z; b$ w+ j8 t4 i" e' I: a( V$ z \) P0 {2 {' z
' y2 ]+ e0 \; Q( w J7 W4 w
5 |) h: E4 ` U, u1 M函数指针的声明 ' M; K: i! U9 ~( X' p# \单个函数指针变量定义步骤# r+ _+ _ @" \5 a. Q
定义一个函数。void fun1(int a, int b); int fun2(double a); 5 }9 n R: C' M, ]用括号把函数名称包围起来,然后在名称前面加*号。void (*fun1)(int a, int b); int (*fun2)(double a);! v2 C, b# _9 H1 P- q" N
如果要定义函数指针数组,在定义单个函数指针的基础上,在名称后面加上[数组长度]void (*fun1[2])(int a, int b); int (*fun2[10])(double a); \( {6 R7 q4 E9 [2 h0 }% U Ttypedef定义函数指针 . |0 h: P$ V1 {可读性高比单个定义要高,特别是声明多个同类型的函数指针,或者函数指针数组。 7 v1 f9 l5 R( V- a, _+ J2 \! s 3 r8 M6 K6 `4 dtypedef定义函数指针的语法! L3 M6 B" y3 L% @/ Q0 S5 U
typedef有两种做法, 一种就是定义一种函数对象,另外一种就是定义函数指针。用法稍稍不同,效果是一样。其中函数对象不支持赋值, 但是支持引用。" B, V' L' ?* r) k( X+ `
8 B; H7 h7 U. I+ e0 C7 Xtypedef int FuncObject(int a, int b); // FuncObject类型是函数对象 7 m9 X( [5 j F3 B$ `' dtypedef int (*FuncPointer)(int a, int b); // FuncPointer类型是函数指针 9 C* t$ r, c- S4 |1 nFuncObject* f1 = &Add;7 I; ]) c' X0 V( O) R
FuncPointer f2; + b" _1 A+ E( F! Kf2 = f1; // f1, f2类型一样, 都是形式为int(int, int)的函数的指针。 ! j8 Y" I! d/ G" cFuncObject f3 = Add; // 报错! 函数对象不支持拷贝 2 e5 G# k) [' R T" o- I3 O9 U0 n9 @FuncObject f4 = &Add; // 报错!&Add是函数指针,与函数对象类型不匹配( H; r; {/ } c( j5 n
FuncObject& f5 = Add; // 正确* o$ p1 {) Y: c% Q0 G+ s
int ret = f5(2, 3); // 正确* G1 e* [' H' I% d
FuncObject& f6 = &Add; // 报错!&Add是函数指针,与函数对象引用类型不匹配' n# K& |! }5 S/ w$ e3 b
如何记住typedef定义函数指针的步骤6 t& P2 Z7 H1 o7 }: @+ P
像定义一个函数指针那样, 指定一个名称。int (*CalFun)(int a, int b); - n( c& a! k6 B+ }+ W在这个函数指针变量声明前面加上typedef。typedef int (*CalFun)(int a, int b);; m* ^' }0 o# j' ]2 O+ f* ?" G
完整例子 ; S" a) o7 l4 u4 m; Jtypedef int(*CalFun)(int a, int b); / L: U1 L& E. p- W8 n5 \ ( P! p1 `6 p7 d; ? W1 Pint Add(int a, int b)* e. S+ b7 a; @" u1 m2 g- y1 V
{- |; e9 @! i5 ~4 ?, B1 Y
return (a + b);) P# F- k' N% f- H {. q
} 6 {' u& j! J7 h) Y- V# q) K8 D8 m5 W) A$ k' B
int Sub(int a, int b)+ Z" c0 @! m6 ^" a; D
{ , w3 f1 C7 a9 _ E return (a - b);0 @8 t8 ?, N; {8 n
}* e# B) S6 H: m7 s, |1 n
6 b0 T2 u) c4 o6 M! S
int main(int argc, char** argv)8 c& c( ?9 d9 T! w. C" k" m
{ " O X! f% x8 M CalFun f1 = Add;/ j7 d4 t( i) g+ B6 S3 ^" y
CalFun f2 = Sub;! A1 T; B3 ?4 v2 u" \# }5 n# [
int a = f1(2, 3);% k/ z+ r% n- O4 h* L+ H' c) h' `' |
int b = f2(10, 5);) x' s8 V E: g/ B3 s4 x5 R" I& ~: N
. K2 z; V, J* J' ^1 V6 x' l7 s- V // typedef定义的函数指针数组。' y. _( W8 f6 I) O a! o+ E
CalFun f_ary[2];& j8 N/ F; }* a- ?" q, F
f_ary[0] = Add;6 c+ u' s, w6 l3 `8 ~3 f3 S- |% Y
f_ary[1] = Sub; 2 c- ~- c/ R: V1 n x0 u ; n1 a. s; T& A+ v8 F6 e5 g // 单个定义的函数指针数组。1 i, J( P3 M4 r3 H
int(*f_ary2[2])(int a, int b); # J$ I; M R( k9 I) Y% V- D, Z f_ary2[0] = Add; o& b5 U6 X) H8 M M u; ?5 E- m8 Z
f_ary2[1] = Sub; 9 g. v, k9 g1 V" Y# c$ E! R0 y7 {& ?8 w! {
return 0;7 k1 H7 C. F5 r( m' R$ L) p
}; X( n A/ o/ j m1 y
4 z5 C/ s8 K% s8 @
using别名定义函数指针 , M- O; O' A1 i" Xc++11以后的类型别名定义--using也可以用于定义函数指针, typedef的好处它都有,个人感觉比typedef更直观。using类型别名同样分函数对象和函数指针两种方式。 $ ^* w8 |+ G3 \7 \& I& S" B# u/ r' g |; X, ^* z ]
typedef int FuncObject(int a, int b); // FuncObject类型是函数对象 6 a; R* ` x# \ L+ _using FuncObject = int(int a, int b);6 d% I7 E4 ]/ R3 b* S3 X
typedef int (*FuncPointer)(int a, int b); // FuncPointer类型是函数指针0 Q# v0 s' L# p X. j% k6 \' _- X
using FuncPointer = int(*)(int a, int b);0 G, [* j$ b; B o
函数指针的调用 , L) u; H* U5 q% ^% W函数指针和函数对象都可以直接后加括号调用 $ Z: s. n, Y& _8 Cint f();" ~: K9 b$ F1 D: q
int (*p)() = f; // pointer p is pointing to f( U$ o+ e2 F' q; ~" `
int (&r)() = *p; // the lvalue that identifies f is bound to a reference( v& E" F! L+ p8 [9 D
r(); // function f invoked through lvalue reference: E6 Z2 ?9 A6 c8 B$ D1 W: c1 Q, B
(*p)(); // function f invoked through the function lvalue - U8 U- O' R& |4 k! ep(); // function f invoked directly through the pointer4 }3 ^8 _ N+ s8 B
如果函数有重载, 函数指针会指向匹配的那个版本。 . y; h; e' a6 ^3 X6 Btemplate<typename T> 2 n4 b+ L' t5 c( {) bT f(T n) { return n; }) ^, v m; {0 S: L7 y: ^: {6 _
' O- v. \, Q: A4 h7 a4 X5 X& p6 r& Hdouble f(double n) { return n; } & Y9 a2 b$ [$ f3 h' S $ }! n, Z6 r6 z% V: b9 pint main()5 T' @5 J' r$ t9 I
{ ) g" X/ ?6 B ^( s- t* x int (*p)(int) = f; // instantiates and selects f<int> 2 B1 i" n8 h4 ]# f}3 q) q, O+ H/ _' x! t
成员函数指针0 h0 [7 R0 V* \/ X8 F: j
静态成员函数,除了增加了访问控制以外,跟普通的函数指针没什么区别,所以普通函数指针可以直接指向类的静态成员函数。但非静态的成员函数与普通函数指针不太一样,声明时需要指定函数归属的类名,并且调用需要指定对象实例。 . O9 D& i9 @; S1 T; U9 { & } B% v. U1 T- b成员函数指针定义。 . U8 A1 T" C# C% z- j+ T像定义类成员函数实现那样写, 并任意指定名称,这里作func。void ClassName::func(int); / |/ `5 f1 d( E, ` P7 t' {1 i括号把类名、范围解析运算符::、名称包围起来。void (ClassName::func)(int);# g" f5 z" w& s8 g1 _4 w3 k( e
在名称的前面加个*号void (ClassName::*func)(int);- e) {5 m* J. q# l; b8 p- \
成员函数也支持typedef和using的定义方式。typedef void(C::* MemberFunc)(int); using MemberFunc = void(C::*)(int);' n2 |6 h# W5 s. r
成员函数指针如何调用。% y* W; P' u7 R5 Q7 p8 H
假设成员函数指针名字为func , {/ @) b) B. l% b1 K: G $ Y, p2 P, G: B* w. J0 ~9 \void (ClassName::*func)(int); 7 `+ r' T0 ~) A4 I) M( e0 _" G0 Z% q: r对象式调用。 2 h3 ?8 G1 ~' u0 V$ P& m; U# aClassName c; // 被调用的对象 1 \! K; D6 d2 X1 e, A成员函数指针名字当作正常函数那样写。( M! `$ [% R" I
c.func(3); 8 y9 Y/ V6 v- y0 I成员函数指针是指针, func名称前面需加上间接寻址运算符*,变成函数对象。 ' _+ g: \3 ?! x& Q7 k8 z: G4 \c.*func(3); # j Q4 \- x( s: M# x最后用括号把调用对象、成员访问运算符.、间接寻址运算符*、和成员函数指针的名称包围起来。! n4 O/ j! [3 G0 T- T
(c.*func)(3);4 E; y, ?5 W% x3 g
为何要加上括号? 根据c++的优先级标准,取成员运算符. > 函数调用() > 间接引用符*。 *号优先级比函数调用要低, 成员函数指针还没取得对象就被调用了,自然报错。 另外 . q( i9 Z( |1 N$ q4 o1 S d(c.(*func))(3);( O, v( ]* Q7 G3 K+ C9 o M. H
这样的写法也不行。 .*和->*是整体作为一个运算符的,中间不能用括号隔开。7 }2 |. Q* Q' h u& m# X
指针式调用, A @1 C ^' y" L5 j# S
ClassName* p; // 被调用的对象的指针8 x& k& _9 i0 ?& Q9 h7 m" E
成员函数指针名字当作正常函数那样写。 l: u: W7 c; m
p->func(3);8 ?7 p" b* h! D: q7 A7 H
成员函数指针是指针, func名称前面需加上间接寻址运算符*,变成函数对象。2 W7 H5 C0 C* K$ `
p->*func(3);$ L5 R P$ D0 r7 d w3 S0 L
最后用括号把调用对象、成员访问运算符->、间接寻址运算符*、和成员函数指针的名称包围起来。1 c, x9 R* D2 r
(p->*func)(3);! F, d$ n; q3 n
函数指针使用完整例子. w! h! J. u: E* V5 ^( Q) m
struct Cal 0 ]! _2 F8 o1 n{ 9 q) a6 D4 e: c, Q7 k" q int add(int a, int b); 9 I2 a3 H2 L2 k2 |" L! p, L4 } ^+ y
int sub(int a, int b); ( b2 o5 {8 Y' H};! X9 Y/ A- {! b. o, d
0 {- H. [4 ? A
int main() 0 u' u0 g+ j$ e# g: m1 o{ $ t1 K; b" V2 D; l# Q( c- b int (Cal::*fun)(int, int) = &Cal::add; : M- v' [3 @7 g- e fun = &Cal::sub;% l0 K0 M5 c" \5 A. _3 k9 S
, B7 u( f# w) P6 B
Cal* p_cal = new Cal();- O* Z. Y4 x. L
int r1 = (p_cal->*fun)(2, 3); $ B. ?3 G+ R& n; a$ T; t8 } delete p_cal;/ g% o% n- Q+ k2 n* e1 n
+ V4 J5 o" a+ n$ t) R
Cal local_cal; $ @* W5 M1 ~: c int r2 = (local_cal.*fun)(8, 6);- J& M8 @' t: P% C9 C
} r. L* o# G, f) G! I; U
; y' N; E+ h1 s& t成员变量指针) i/ [: z" k; k
成员变量指针比成员函数指针还要简单些,没有函数调用, 无需考虑函数调用和间接引用符*的优先级问题。 8 I/ u# w; M8 K2 O2 R6 v9 L) H 2 `4 u- k/ c$ j# z2 R" r成员变量指针的定义 ' @7 A) @0 w: M3 @假如以下结构体C。 7 ^/ C/ ^/ ?' J ) o: Z6 X0 X1 R1 cstruct C , W& U; k( W. w: ?- n{ 3 P7 J! m; \, [0 N
int m; 9 U B. C M7 T2 C9 S: D$ D
}; 9 R9 W6 y- n# S; d: ~5 V' T% s单个成员变量指针定义 ' c* i. t. O6 l4 y8 \% w假设名称为p, 类似静态成员变量定义那样声明6 L2 f% Z) M0 p; N: J$ p
int C::p;! ? j. [0 v/ M2 L
在名称前面加上指针标识号* 9 a( X- k5 {; F' i6 V2 R. y
int C::*p;1 N/ V2 p/ u& m
typedef或using方式定义 # g- j& q7 Q& z$ f- Htypedef int C::*MemberPointer; 8 U4 A( m) k' n( w7 ^using MemberPointer = int C::*;# ^: L7 ~, B- z# p9 z
成员变量指针的使用。0 d9 P9 t6 y# |% U& _5 X
类似成员函数指针那样,直接使用指向成员的指针运算符:.* 和->*即可。 6 L6 X% ^ c. H) d& b% T. M; s: `, W) H成员变量指针, 能让我们实现一些遍历成员的动态功能。 例如把一个类/结构体的多个同类型的成员变量放进一个容器里,然后遍历访问这些成员变量。 2 D) g8 D y# B1 ?& U8 Y9 S! U: J: t% `0 ~. }# |, z! w
完整例子7 x" `0 i% x1 ]) y2 R
struct C { int m; };6 f0 x4 L" P. M/ r0 R
int main() * a: V. @5 I% C: C" F{% l A% z" ~, q* P9 D0 h9 k
int C::* p = &C::m; // pointer to data member m of class C4 S' h% B: j6 S' ^1 s
C c = {7};& y' k2 m0 \- T! J6 ?1 \7 f& O w8 \6 L" \
std::cout << c.*p << '\n'; // prints 7 6 H# h# n- V3 ?# ~- \ C* cp = &c;- s M* a" i: u1 ]7 p: `7 B& U3 W+ m2 S+ f
cp->m = 10; ; x$ f) G% `7 g0 C: ? std::cout << cp->*p << '\n'; // prints 106 O+ a0 |" a2 {5 [% z- T; B
8 r& b% o% M8 L+ D$ o————————————————/ ^0 ]+ k2 I5 f8 r3 m7 C
版权声明:本文为CSDN博主「南风fahaxiki」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。: V6 J% ]7 d G
原文链接:https://blog.csdn.net/m0_64407685/article/details/1267881154 V5 u5 d3 h( U' k' H
: B3 k) K3 O' ?& }8 Q, Q
7 M8 K/ I; H6 _! M. y