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

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

[复制链接]
hfndhf123 发布时间:2023-9-25 09:44
TouchGFX是一个基于STM32硬件,由C++写成的软件框架,所以有必要对C++基础有一定的了解
一. C++新特性
, |; k, U0 m* g- v) K- T9 q
C语言里,变量初始化必须在程序的前面,而C++则可以随用随定义。C++也可以直接初始化,比如 int x(100),这样就直接赋值 x=100C++的输入输出方式:以cin和cout代替了C语言里的scanf和printf
cout语法形式:
  1. cout << x << endl;8 k* L; Q5 g& Q! U
  2. // x 可以是任意数据类型(或表达式)
    1 W1 P6 u) C1 H$ }6 q
  3. // endl 是换行符,与C里的"\n"效果一样
    # Y2 Y) y/ D' D6 m( [
  4. cout << x << y << endl;  //多个变量的输出
复制代码
cin 语法形式:
  1. cin >> x;  //x可以是任意数据类型
    1 R2 P6 R! C+ j
  2. cin >> x >> y; //多个变量的输入
复制代码

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

  1. #include <iostream># n6 a- y+ Z5 r# J. j0 v
  2. using namespace std;
      O7 U- z0 p$ i
  3. int main(){
    ! H. q2 S( Z6 i7 j
  4. cout << "Hello, World!" << endl;
    " Y3 K' t- `8 q% \2 N9 W4 I0 y+ F9 B
  5. return 0;+ g* R5 ]8 ?& C0 I2 W7 H
  6. }
复制代码
上面程序中,头文件要写成iostream,因为是标准输入输出流;带".h"的是非标准输入输出流。using是编译指令,声明当前命名空间的关键词,可理解成使用命名空间std,因为cin和cout都是属于std命名空间的,所以使用时须加上using namespace std,也可以写成std::cin和std::cout,其中 :: 表示作用域6 n- s6 v% n; ]- @
为什么要使用命名空间呢?一些名字易冲突,所以会使用命名空间的方式进行区分,具体来说就是加个前缀。比如C++标准库里面定义了vector容器,自己又写了个vector类,这时名字就冲突了。于是使用标准库里的名字时,都要加上std::的前缀,即std::vector来引用。经常写全名比较繁琐,所以在名字没有冲突的情况下可以添加using namespace std,那么接下去使用标准库里的名字时就可以不用再写std::前缀了
  1. /***** namespace_example.cpp *****/! e# u+ Q( i/ O* J, g# x! }3 b1 z% d6 {
  2. #include <iostream>1 W* S$ X. J) x& w
  3. using namespace std;
    $ v8 Y2 k5 _. G/ d
  4. namespace A { //自定义命名空间A
    : b/ e1 w! H+ Q6 G! t+ {; S2 S
  5. int x = 1;
    : k( f* S2 j9 E. S) P
  6. void fun() {$ \- q. ]% i. z' P: K+ r/ I% |, \
  7.   cout<<"A namespace"<<endl;
    5 V. ]  J, |$ U8 [4 [
  8. }
    ) B: W( \' y. b$ ^
  9. }
    : {1 `( ~: ]( L4 `* T
  10. using namespace A; //声明使用命名空间A
    2 i: V3 t3 ]; J4 }/ M9 G' B
  11. int main(){( |) R  H, x. [9 n! }# B
  12. fun(); //声明使用命名空间A后,可直接使用fun()
    5 i& Q/ `* h8 G3 g5 ?% {
  13. A::x = 3; //将A命名空间下的x重新赋值为31 n& K% ~; A! j' t" l. o
  14. cout<<A::x<<endl;
    7 `0 @1 e7 t; |; E  E8 U
  15. A::fun();
    9 f2 q* Z  h5 J7 G  k# V5 P5 D
  16. return 0;
    7 p% r* t! h& s, s# P7 n& j; r0 @6 ?/ T
  17. }
复制代码
执行下面的指令开始编译
  1. g++ namespace_example.cpp -o namespace_example
复制代码
执行./namespace_example后结果如下
  1. A namespace$ b& i& t4 N7 ]& s
  2. 3# i# O( r6 T$ P* v, N
  3. Anamespace
复制代码
二. C++面向对象
' a7 p# X" n" x/ O  T3 ~
面向对象的三大特征是继承,多态和封装
2.1 类和对象
类是C++的核心特性,通常被称为用户定义的类型。类用于指定对象的形式,包含了数据表示法和用于处理数据的方法。类中的数据和方法称为类的成员,函数在一个类中被称为类的成员。从类中实例化对象分两种方法,一种是从栈中实例化对象,一种是从堆中实例化对象

8 v& @& h9 Q+ D1 F' {; ^5 p$ ?
  1. /***** class_dog_example.cpp *****/$ b5 y' ^, m% K: _. i( F6 P  E0 O
  2. #include <iostream>, w% P4 ?' n  D. }9 I
  3. #include <string>
    # b- \$ h! @: x! M
  4. using namespace std;
    " Q; q2 H6 F" \" W
  5. 5 S  n6 n: D0 r8 K6 U% d
  6. class Dog {  //定义一个类8 i" C: i! U1 {* w7 n  L, g* g5 ]
  7. public:   //访问限定符public(公有的),不写的话默认是private
    / e5 s% S. u$ `( |/ i( @
  8. string name;
    $ W- Z& y* x' X9 ~) x# U7 U
  9. int age;6 k# i4 H) O" F8 k7 Y
  10.   Q$ C1 j9 V0 w* G" B/ K0 p. O
  11. void run() { //定义一个方法
    & d6 M+ r9 c* P
  12.   cout<<"小狗的名字是:"<<name<<","<<"年龄是"<<age<<endl;3 U( R' }8 c; k+ p
  13. }  L  b: G# i2 {/ }
  14. };
    # k% m: I9 ^! N& h
  15. 5 w! k# c' N0 ?* C# _
  16. int main() {  @8 g( P% X3 [( l/ Z6 g" q
  17. /* 从栈中实例化一个对象dog1 */
    ' w) T) j- D) s6 t6 G1 x
  18. Dog dog1;
    4 K8 X3 j) L4 S4 b8 ^
  19. dog1.name = "旺财"; //为dog1的成员变量赋值
    " ^& z! Q) ~% `; ?
  20. dog1.age = 2;  //为dog1的成员变量赋值* t9 z8 N8 R5 \. |: `
  21. dog1.run();   //调用run()方法,打印dog1的相关变量信息
    2 u4 k" Z$ L+ a9 T3 Y7 M
  22. /* 从堆中实例化对象,使用关键字new的都是从堆中实例化对象 */
    8 l! P* r% i8 u6 o0 f
  23. Dog *dog2 = new Dog();
    3 x% x! k& o! C4 M4 }
  24. if (NULL == dog2) { //从堆中实例化对象需要开辟内存,指针会指向那个内存& }7 T7 S! P) ]. s$ U
  25.   return 0;
    . r( ^* l% R# n
  26. }
      P6 [( L: i4 e% h% b2 [  w6 s8 ?
  27. dog2->name = "富贵"; //为dog2的成员变量赋值7 B+ j* l1 L" P, V3 T
  28. dog2->age = 1;   //为dog2的成员变量赋值& `! l' A' q& f  G( q# p
  29. dog2->run();   //调用run()方法,打印dog2的相关变量信息- _" ]2 n. x# x8 N( K3 V

  30. ( M: J1 A4 T9 ]5 `6 k& t, T( E
  31. delete dog2;   //释放内存$ @& l3 C0 W2 `" s9 _' f, ?0 E
  32. dog2 = NULL;   //将dog2重新指向NULL- h5 l. j0 k7 Z+ D1 B. a* B
  33. return 0;, H2 c6 l9 O/ q8 _+ c) N
  34. }- _6 P6 d  ?& E3 q( U
  35. 执行下面的指令开始编译/ j7 M) ^" t' ?7 {7 b  f$ O

  36. , z# ~" `4 ?6 ]3 H
  37. g++ class_dog_example.cpp -o class_dog_example
    7 l7 }) l9 H9 Y% S
  38. 执行./class_dog_example后结果如下/ \$ l+ w8 a* H! S/ m5 O
  39. * ^9 S: u/ p' n3 i+ j
  40. 小狗的名字是:旺财,年龄是2
    ; ]) A4 H5 S& [  x6 P/ m7 L
  41. 小狗的名字是:富贵,年龄是1
    6 M  i/ S# q7 f! e9 y; \
  42. ⏩ 构造函数与析构函数; o$ z) O, C* Y  I7 S3 @- ~
  43. 构造函数在对象实例化时被系统自动调用,仅且调用一次。构造函数的特点如下:
    4 ^# F3 y) E0 j* x2 G3 @) V. ^
  44. 构造函数必须与类名同名6 l8 _( H: h( M* K1 g& u* p' ^# r

  45. $ k2 `9 k; n0 L( l# q# J- t
  46. 可以重载,没有返回类型+ k$ O$ R9 v' J, C  ?7 r& H

  47. 6 V7 d& G, b+ @. f! l
  48. 构函数在对象结束其生命周期时系统自动执行。析构函数的特点如下:
    : m; s: _0 p' U1 z( ^! c
  49. 析构函数的格式为~类名(),调用时释放内存(资源)3 j: Z- v, M* M5 r' W* Q5 Q

  50. 6 k' d! p3 A2 R, K# U8 h8 Y
  51. ~类名()不能加参数,没有返回值
    , e6 s9 ~9 d1 a6 R
  52. 6 \  D: j  ]- l; b2 W/ L% Q2 u4 z
  53. 定义类时, 如果没有定义构造函数和析构函数, 编译器就会生成一个构造函数和析构函数, 只是这个构造和析构函数什么事情也不做。当要使用构造函数和析构函数时就需要自己在类里添加
    6 ?: b# e& A, }) ?( S1 O# `

  54. ) O9 L/ W: U2 g  Y; E( _! j2 h# _7 [
  55. /***** structor_example.cpp *****/
    0 e2 Y& m# Y9 N6 O- Z
  56. #include <iostream>4 l; c; z1 M0 u9 \) X1 A! ^
  57. #include <string>4 d+ n4 j2 o9 f5 D' u; `5 P; T" L
  58. using namespace std;2 |: i/ Z& E/ C( B
  59. 5 t$ e2 q; h: u4 S7 L
  60. class Dog {  //定义一个类,并在里面写了构造函数和析构函数
    ! E0 `9 e$ L1 V4 k2 p3 I
  61. public:% F( K/ F0 S. l! x* M% ^& \
  62. Dog();
    7 \7 T& J" v4 n* P% t" v9 ^
  63. ~Dog();) o5 T. C' l7 g: `% A2 V
  64. };5 t$ [6 u' F3 o$ B; u' q9 v) H
  65. 7 F: e- p  C- u4 k. i" O* V
  66. int main() {
    * l+ m9 e; Y. J+ |5 O
  67. Dog dog;  //实例化一个dog对象
    1 @2 ~: f: K( N, A  R" i+ l
  68. cout<<"构造与析构函数示例"<<endl;
    ' F4 R; d+ |+ s
  69. return 0;4 V, m  J/ j: x3 j
  70. }
    - `" X, w: ^9 j2 m
  71. //类的函数可在类里实现,也可在类外实现,在类外实现时需要使用“::”
    9 c9 j, T/ F" a5 Y" X
  72. Dog::Dog() {
    ' d* ?. W" n7 d9 w$ ^
  73. cout<<"构造函数执行! "<<endl;: `, G- S# R  _- z4 i$ k
  74. }  K1 s. x2 }3 w. d, J

  75. / n7 _! \- E6 D- c$ d
  76. Dog::~Dog() {
    1 a! W! _' \% n* C$ W' ]
  77. cout<<"析构函数执行! "<<endl;
    5 H2 a- y) [0 ]9 H9 d* S. p% l( d
  78. }
复制代码
执行下面的指令开始编译
  1. g++ structor_example.cpp -o structor_example
    ! T; z7 k' ]9 [" _4 D9 \
复制代码
执行./structor_example后结果如下
  1. 构造函数执行!! u, A) J% f% a) e/ n
  2. 构造与析构函数示例
    . ]; F6 W0 _, J
  3. 析构函数执行!
复制代码
this指针
每个对象都拥有一个this指针,this指针记录对象的内存地址。this指针是指向类自身数据的指针,简单来说就是指向当前类的当前实例对象。关于类的this指针有以下特点:

/ e5 }' W; ^1 j6 v: ?0 Q' ~0 G9 A; U
  • this只能在成员函数中使用,全局函数、静态函数都不能使用this
  • this在成员函数的开始前构造,在成员函数的结束后清除
  • this指针会因编译器不同而有不同的放置位置。可能是栈,寄存器或者全局变量
    ' t: r( {  h/ c6 r, D
  1. /***** this_pointer_example.cpp *****/
    # Y5 Z9 U4 U& z) _5 R0 @
  2. #include <iostream>
    6 w% d) g! I" D* |& ^/ I2 v
  3. #include <string>3 a, x/ G2 ?% A. V& i, h
  4. using namespace std;
    1 S) [1 a! D4 M9 i9 m! b2 {
  5. ! q  z4 @( k+ _+ y' c
  6. class Dog {" F( ]( u2 l& m2 N: m% |
  7. public:, u% z6 \. r. ]( x6 @! ?
  8. string name;
    / W0 k7 v% F4 h) a5 e. `4 l. H
  9. void func();; ^5 p; d: v2 _# @! l2 l5 Z
  10. };' \! P6 `9 a! Q) C7 y

  11. ; V8 X/ Q  p4 G7 s
  12. int main() {$ Y* d, {% W* m. R) I
  13. Dog dog;
    ' R5 c+ K2 G. ?0 e
  14. dog.func();4 l* g0 r4 f; }+ F7 Z# S+ [! W
  15. return 0;# T6 ~  }  s. Q0 c" [
  16. }
    0 n) S: O7 c$ q% }5 H2 ]
  17. //在类的成员函数里使用了this指针, 并指向了类里的成员name
    9 {1 I4 z6 M* Y
  18. void Dog::func() {5 N! v, c) U/ X. x9 O( d
  19. this->name = "旺财";/ X" D4 ~; b5 P) F
  20. cout<<"小狗的名字叫: "<<this->name<<endl;& ]- Q& w0 }: L! i. N; m
  21. }
复制代码
执行下面的指令开始编译
  1. g++ this_pointer_example.cpp -o this_pointer_example
复制代码
执行./this_pointer_example后结果如下
  1. 小狗的名字叫:旺财
    : I" W* i, x% I3 j
复制代码

1 n; W' B  e3 O* n2 C- f
转载自嵌入式攻城狮

. Q: z4 W* w4 Q1 w- h4 i

4 N/ }; K0 I1 f# G' y
收藏 评论0 发布时间:2023-9-25 09:44

举报

0个回答

所属标签

相似技术帖

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