你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

TouchGFX界面开发应该知道的 C++基础(1)

[复制链接]
hfndhf123 发布时间:2023-9-25 09:44
TouchGFX是一个基于STM32硬件,由C++写成的软件框架,所以有必要对C++基础有一定的了解
一. C++新特性
. |; s/ m. r. x5 |
C语言里,变量初始化必须在程序的前面,而C++则可以随用随定义。C++也可以直接初始化,比如 int x(100),这样就直接赋值 x=100C++的输入输出方式:以cin和cout代替了C语言里的scanf和printf
cout语法形式:
  1. cout << x << endl;) O* h8 `3 E2 ?% K" |, S
  2. // x 可以是任意数据类型(或表达式)+ Y, q: Z! U2 u; ?- B
  3. // endl 是换行符,与C里的"\n"效果一样3 f7 A- c6 Q0 r
  4. cout << x << y << endl;  //多个变量的输出
复制代码
cin 语法形式:
  1. cin >> x;  //x可以是任意数据类型
    & g) n' H! B& L2 O3 k
  2. cin >> x >> y; //多个变量的输入
复制代码

C++的命名空间 namespace:using namespace std;

  1. #include <iostream>* J. V, n+ j; @3 v' c
  2. using namespace std;1 I9 d! h! Z8 s
  3. int main(){7 E) B! f* J$ u. l9 z3 l
  4. cout << "Hello, World!" << endl;
    ( l) S% G9 O; x$ l! S% \4 p
  5. return 0;
    8 F1 z0 y5 @* f* d0 e
  6. }
复制代码
上面程序中,头文件要写成iostream,因为是标准输入输出流;带".h"的是非标准输入输出流。using是编译指令,声明当前命名空间的关键词,可理解成使用命名空间std,因为cin和cout都是属于std命名空间的,所以使用时须加上using namespace std,也可以写成std::cin和std::cout,其中 :: 表示作用域) _3 ?4 Y( ]3 u2 q( d: p1 l! i
为什么要使用命名空间呢?一些名字易冲突,所以会使用命名空间的方式进行区分,具体来说就是加个前缀。比如C++标准库里面定义了vector容器,自己又写了个vector类,这时名字就冲突了。于是使用标准库里的名字时,都要加上std::的前缀,即std::vector来引用。经常写全名比较繁琐,所以在名字没有冲突的情况下可以添加using namespace std,那么接下去使用标准库里的名字时就可以不用再写std::前缀了
  1. /***** namespace_example.cpp *****/# O3 X$ B+ ]  I) E' @
  2. #include <iostream>
    9 R4 p+ T" I/ V
  3. using namespace std;
    + J5 K8 N' {  l& w( N: b6 I+ y
  4. namespace A { //自定义命名空间A
    " G9 L. m) T% R9 I2 J( S9 q
  5. int x = 1;
    $ a4 o; Q2 X) |1 w
  6. void fun() {
    : B! V& F1 `1 @& Y0 b
  7.   cout<<"A namespace"<<endl;* x& C4 y( }) q7 `3 y( X) ?
  8. }% V* w' z; i% s- }0 K" L1 \! p
  9. }, E- M3 _; J: ]9 f2 W
  10. using namespace A; //声明使用命名空间A
    - L( Y" k& a" q3 G' R6 x& i
  11. int main(){
    + v) Z8 ~; E- y$ y. n
  12. fun(); //声明使用命名空间A后,可直接使用fun()
    1 c) r7 {! {6 l5 H4 j; c2 h9 a
  13. A::x = 3; //将A命名空间下的x重新赋值为3
    * o3 @6 N: b/ [. {' C+ Q7 x1 l) j4 n! j
  14. cout<<A::x<<endl;8 a* j7 H& c: u* r8 ~
  15. A::fun();
    7 Q2 D' k% `7 j! S$ ]) }5 @. J
  16. return 0;
    1 V/ A: ]1 V" \
  17. }
复制代码
执行下面的指令开始编译
  1. g++ namespace_example.cpp -o namespace_example
复制代码
执行./namespace_example后结果如下
  1. A namespace
    ( c- S" M9 M3 V2 l% y. W7 w/ a
  2. 38 @- w" u( e- |6 ~. g
  3. Anamespace
复制代码
二. C++面向对象

; p( @, c4 \+ X) i5 O
面向对象的三大特征是继承,多态和封装
2.1 类和对象
类是C++的核心特性,通常被称为用户定义的类型。类用于指定对象的形式,包含了数据表示法和用于处理数据的方法。类中的数据和方法称为类的成员,函数在一个类中被称为类的成员。从类中实例化对象分两种方法,一种是从栈中实例化对象,一种是从堆中实例化对象
) w! ~3 K( h) G) W  Q
  1. /***** class_dog_example.cpp *****/
      y1 N# h" M" u( G/ a7 @) P
  2. #include <iostream>
    * ~' Y! o) ^$ r
  3. #include <string>
    ) H; A2 y0 t! o; s5 D, O
  4. using namespace std;7 h7 o% ]1 \: H5 P& N
  5. + s7 A$ P( H' P0 u5 g5 y
  6. class Dog {  //定义一个类% @* x, B$ A# O2 _
  7. public:   //访问限定符public(公有的),不写的话默认是private
    * q( b( n. g8 w9 h/ p, S
  8. string name;
    8 }" _( I6 Z  b) k
  9. int age;0 C1 m6 t! g$ V+ j/ `6 P  D

  10. " u% H2 [4 w- c' L( e8 v4 H
  11. void run() { //定义一个方法
    # Y1 R9 J7 q, X: v6 S: i
  12.   cout<<"小狗的名字是:"<<name<<","<<"年龄是"<<age<<endl;
    ' N; h( {0 I' v
  13. }# R* |: ]% F, o) T
  14. };' S' _  ]/ R  W7 {0 R8 v
  15. ' s6 k+ m5 A; i  Y* L& ~" M* H) H
  16. int main() {
    8 E/ _' S/ h% ^  v7 G
  17. /* 从栈中实例化一个对象dog1 */
    . O& ?: g0 I, }: o
  18. Dog dog1;
    ! V: q. m3 z, B: P7 D2 s* a
  19. dog1.name = "旺财"; //为dog1的成员变量赋值
    * I: Z" L  `  N8 ]2 _3 L4 p# @/ x
  20. dog1.age = 2;  //为dog1的成员变量赋值
    & s3 w5 M7 l/ S; A+ V& z! C/ T9 o
  21. dog1.run();   //调用run()方法,打印dog1的相关变量信息
    ( c  C5 t9 [+ O. E1 m, F: l/ W
  22. /* 从堆中实例化对象,使用关键字new的都是从堆中实例化对象 */
    0 H: ?( S6 ^" U: ]7 @/ M) K
  23. Dog *dog2 = new Dog();
    # _; s5 U! O* r" {3 q8 Z
  24. if (NULL == dog2) { //从堆中实例化对象需要开辟内存,指针会指向那个内存
    ( x3 S' R1 b6 V3 h& z  x
  25.   return 0;4 i4 {/ q% z1 K8 K% B3 A/ y  g
  26. }
    $ q# T8 K- }. q9 X7 F
  27. dog2->name = "富贵"; //为dog2的成员变量赋值( `- Z6 i: \& `) |: q+ ~2 \
  28. dog2->age = 1;   //为dog2的成员变量赋值
    & @' B2 N7 h& e( _: v; ?
  29. dog2->run();   //调用run()方法,打印dog2的相关变量信息
    4 N6 ^& C1 b( A( k' t- v9 f2 l

  30. ; }' y0 `3 D/ O' I9 C4 T3 d( D' A
  31. delete dog2;   //释放内存
    2 d! F: _: O" W( f/ {% Q
  32. dog2 = NULL;   //将dog2重新指向NULL
    % U5 t3 a! M7 ~6 W+ p3 n$ L
  33. return 0;
    # c- v+ S9 ^: p& A
  34. }
    " r: q! h, c* L4 Y" {, Z' ?) l
  35. 执行下面的指令开始编译
    9 a0 ?* C' @0 h+ N" M) e
  36. 3 o! r/ T7 U; B# d$ R) t* D" N  ~3 ?
  37. g++ class_dog_example.cpp -o class_dog_example& V9 z, A- r7 r+ e6 d3 g
  38. 执行./class_dog_example后结果如下
    2 d8 `. P5 k' o2 [

  39. 3 j; H5 e$ y" z4 v7 b, e. ?; \; ]
  40. 小狗的名字是:旺财,年龄是2, x5 {1 i8 d0 _' H' t
  41. 小狗的名字是:富贵,年龄是1
      ^* a( h; D1 c& W  \
  42. ⏩ 构造函数与析构函数9 b5 W5 b/ ~  o0 G
  43. 构造函数在对象实例化时被系统自动调用,仅且调用一次。构造函数的特点如下:
    % {& _+ f! T) ^( G7 @/ j) t% I
  44. 构造函数必须与类名同名5 w( H, f+ N5 j' z; k

  45. 6 e) m2 t' s" g/ O2 f5 ^2 k
  46. 可以重载,没有返回类型
    6 S) d- c9 d* m; B2 {7 y0 `1 ]
  47. : _* Y8 T" B1 G8 Z( w
  48. 构函数在对象结束其生命周期时系统自动执行。析构函数的特点如下:
    / d8 c9 W& M; ~. b  g/ \
  49. 析构函数的格式为~类名(),调用时释放内存(资源)
    / w% i+ k3 ~+ a5 H$ c

  50. , N! O5 n8 G1 i3 \
  51. ~类名()不能加参数,没有返回值
    / C+ y& W( s$ t- `) ^/ X
  52. ; {9 a. t0 O- a
  53. 定义类时, 如果没有定义构造函数和析构函数, 编译器就会生成一个构造函数和析构函数, 只是这个构造和析构函数什么事情也不做。当要使用构造函数和析构函数时就需要自己在类里添加/ \7 H1 z9 [2 h

  54. , j1 E) x# N: j8 p, Q% J. I- k
  55. /***** structor_example.cpp *****/5 O. W# M. Z$ j
  56. #include <iostream>
    7 Z3 K( S' ]/ h9 j0 i$ G, F" t. x3 T
  57. #include <string>
    6 L% X: D0 v8 m' G; H7 \5 |
  58. using namespace std;: V3 A1 F- }, @' G1 _
  59. 8 m/ V$ h+ ?6 M% P
  60. class Dog {  //定义一个类,并在里面写了构造函数和析构函数
    0 ?7 s; d) k" p) ?# {. W% E
  61. public:4 u5 b( f5 }$ w5 V$ R3 `
  62. Dog();* X. F- b1 _% [3 g' h
  63. ~Dog();
    ' ?4 V6 l4 A+ Z5 J% a- S
  64. };- C( E$ L) W+ Y/ f9 K6 }

  65. 7 B# U  A- G7 C5 K4 R' N; W( R% V
  66. int main() {
    ; z' g2 G4 z! `' ?* R, u! I- n
  67. Dog dog;  //实例化一个dog对象
    " h/ m! \& H/ |" \. \
  68. cout<<"构造与析构函数示例"<<endl;  J* }' x! l7 ~) P& P5 ~- c7 @  p
  69. return 0;: b. l$ f/ C# U& ?
  70. }" N, \: S  ~" Y
  71. //类的函数可在类里实现,也可在类外实现,在类外实现时需要使用“::”
    7 y$ \. n* x: i3 K: o' X& Q0 Q( E
  72. Dog::Dog() {6 U6 O' t. L, N) n5 K3 z
  73. cout<<"构造函数执行! "<<endl;& _& Y5 q- x* s' W9 Y
  74. }
    4 l) t: C3 |# o- }) ~

  75. & b0 o7 y! v" z; w6 c
  76. Dog::~Dog() {: R+ o3 k$ E( c+ \) Q4 a% E" `
  77. cout<<"析构函数执行! "<<endl;0 e& M! G, C0 N5 S; ~2 [# M7 |
  78. }
复制代码
执行下面的指令开始编译
  1. g++ structor_example.cpp -o structor_example4 h0 v5 t* F# W5 i) g8 C4 t
复制代码
执行./structor_example后结果如下
  1. 构造函数执行!
    8 h+ ~) _! m/ x
  2. 构造与析构函数示例' W0 A5 h7 Y7 D& F4 k; I
  3. 析构函数执行!
复制代码
this指针
每个对象都拥有一个this指针,this指针记录对象的内存地址。this指针是指向类自身数据的指针,简单来说就是指向当前类的当前实例对象。关于类的this指针有以下特点:

& h1 w: @+ r- p- c+ |7 z7 Z! \. }
  • this只能在成员函数中使用,全局函数、静态函数都不能使用this
  • this在成员函数的开始前构造,在成员函数的结束后清除
  • this指针会因编译器不同而有不同的放置位置。可能是栈,寄存器或者全局变量
    " t% l1 o; k( S. d' q
  1. /***** this_pointer_example.cpp *****/) ]0 b+ w" T+ c1 b
  2. #include <iostream>  h# u) D& C  O# c. |; f' Y
  3. #include <string>' ^- I$ h9 b5 p/ e
  4. using namespace std;
    ! I  F8 z. S/ L, c9 q1 m' K5 C
  5. ' `% S  y1 |3 a9 c! ~% J$ f
  6. class Dog {8 ]$ h9 E! {. l7 Q( n
  7. public:
    9 A2 H2 z' M" E5 k) ^4 c
  8. string name;+ \3 _/ P: p+ {: g" O3 s+ \
  9. void func();
    : W: J. N2 p; L6 i
  10. };; N# I: s; |" e, S( M& t

  11. , |/ m5 j# J5 t
  12. int main() {) n& p, w6 I+ |& p2 o
  13. Dog dog;) `) Y7 p5 J4 b* s/ j
  14. dog.func();! l9 t* @3 c9 W
  15. return 0;% \3 J" S2 v8 H
  16. }
    7 g$ q# x7 d, B
  17. //在类的成员函数里使用了this指针, 并指向了类里的成员name! U1 t/ j; U) b: k
  18. void Dog::func() {3 E# Y& E1 V6 ~: l7 R  Q7 Z+ Y
  19. this->name = "旺财";8 V& [' A, B8 N8 N
  20. cout<<"小狗的名字叫: "<<this->name<<endl;
    ( j0 a: I7 A& B: b' k' w
  21. }
复制代码
执行下面的指令开始编译
  1. g++ this_pointer_example.cpp -o this_pointer_example
复制代码
执行./this_pointer_example后结果如下
  1. 小狗的名字叫:旺财) @- K7 F$ J* A( q
复制代码
9 W6 Y" {& U8 N0 g
转载自嵌入式攻城狮

0 z; R2 x- O: r% A

! ^  r0 S% ]# i" q6 f7 x8 g
收藏 评论0 发布时间:2023-9-25 09:44

举报

0个回答
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版