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

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

[复制链接]
hfndhf123 发布时间:2023-9-25 09:44
TouchGFX是一个基于STM32硬件,由C++写成的软件框架,所以有必要对C++基础有一定的了解
一. C++新特性
4 Z7 M  ?! N4 z: D' j6 j# d! U5 [
C语言里,变量初始化必须在程序的前面,而C++则可以随用随定义。C++也可以直接初始化,比如 int x(100),这样就直接赋值 x=100C++的输入输出方式:以cin和cout代替了C语言里的scanf和printf
cout语法形式:
  1. cout << x << endl;6 M: ~/ \, g# M' s; D
  2. // x 可以是任意数据类型(或表达式)
    * y( M: ^; g3 Z
  3. // endl 是换行符,与C里的"\n"效果一样3 b# P2 R  a, T1 F& |/ Z7 D
  4. cout << x << y << endl;  //多个变量的输出
复制代码
cin 语法形式:
  1. cin >> x;  //x可以是任意数据类型
    & p  a% }  @. P+ v
  2. cin >> x >> y; //多个变量的输入
复制代码

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

  1. #include <iostream>
    0 ~- j3 B; K) o
  2. using namespace std;
    # P8 s& ?! O! X. b. C
  3. int main(){
    7 @( `7 a7 B/ C2 |5 C+ o$ F
  4. cout << "Hello, World!" << endl;3 W. a1 H" t2 E0 j" M9 t0 @, ]
  5. return 0;
    5 v' O" x; g2 C/ F3 v
  6. }
复制代码
上面程序中,头文件要写成iostream,因为是标准输入输出流;带".h"的是非标准输入输出流。using是编译指令,声明当前命名空间的关键词,可理解成使用命名空间std,因为cin和cout都是属于std命名空间的,所以使用时须加上using namespace std,也可以写成std::cin和std::cout,其中 :: 表示作用域6 x0 i/ ?. h+ ?- U! C+ j
为什么要使用命名空间呢?一些名字易冲突,所以会使用命名空间的方式进行区分,具体来说就是加个前缀。比如C++标准库里面定义了vector容器,自己又写了个vector类,这时名字就冲突了。于是使用标准库里的名字时,都要加上std::的前缀,即std::vector来引用。经常写全名比较繁琐,所以在名字没有冲突的情况下可以添加using namespace std,那么接下去使用标准库里的名字时就可以不用再写std::前缀了
  1. /***** namespace_example.cpp *****/
    2 t# u+ [6 Y; X# `
  2. #include <iostream>4 S8 o6 c# S9 y' `1 @
  3. using namespace std;
    " Z& z6 r) N; w7 l6 K8 O0 ]) J6 [) n
  4. namespace A { //自定义命名空间A
    ! c+ a. ?. ]! R$ ]: H
  5. int x = 1;
    2 a- G. W; y  i. g0 v" g( B
  6. void fun() {& E' l& [  ?9 E3 V3 b, ]4 V
  7.   cout<<"A namespace"<<endl;, [; f& g/ f8 ]6 I. @
  8. }; p' B+ K! I  j6 P8 q3 P/ Q! r5 D  t
  9. }
      c) T; E3 U# N- P: I0 G
  10. using namespace A; //声明使用命名空间A! g/ c8 D% F% ^0 \3 O! X! X6 c* y3 Z* P
  11. int main(){
    8 B! e+ U2 x/ n# X' F
  12. fun(); //声明使用命名空间A后,可直接使用fun()+ g! y* i9 F$ I
  13. A::x = 3; //将A命名空间下的x重新赋值为3
    : p5 U" b6 Z5 d& I, Q# d
  14. cout<<A::x<<endl;) h* K: z) v4 y2 h
  15. A::fun();' K2 X" }  l. c! E
  16. return 0;
    4 d* V4 j( h8 l: o
  17. }
复制代码
执行下面的指令开始编译
  1. g++ namespace_example.cpp -o namespace_example
复制代码
执行./namespace_example后结果如下
  1. A namespace
    - f) R( |2 o0 H; I+ L/ ?
  2. 3
    7 O# R. z$ Q+ r) [! s7 ~0 Q/ o$ e
  3. Anamespace
复制代码
二. C++面向对象

: [9 E6 a$ O$ H) z) K
面向对象的三大特征是继承,多态和封装
2.1 类和对象
类是C++的核心特性,通常被称为用户定义的类型。类用于指定对象的形式,包含了数据表示法和用于处理数据的方法。类中的数据和方法称为类的成员,函数在一个类中被称为类的成员。从类中实例化对象分两种方法,一种是从栈中实例化对象,一种是从堆中实例化对象
3 r! w1 K" l2 q6 b) ~
  1. /***** class_dog_example.cpp *****/
    , z, o+ r; W  ^0 \2 L- q7 |  T
  2. #include <iostream>
    9 A& S, {% F! q# e
  3. #include <string>
    ' Z& m! |. D- r: f/ D8 _
  4. using namespace std;/ ^0 b% ~# J: H. g- p1 Q3 O
  5. $ N8 d; ?+ }$ M) J7 |
  6. class Dog {  //定义一个类) I6 V" U& C. x# }4 f% k0 |! R
  7. public:   //访问限定符public(公有的),不写的话默认是private, C& f% v4 [* j4 ]5 M  C
  8. string name;
    0 s/ Y8 m& ?, h# y+ ^- Z
  9. int age;' h- U5 B0 a+ r' \2 W; `' I

  10. * Z! ?* I+ \" C' _5 H7 ^, m6 P3 |0 V
  11. void run() { //定义一个方法8 H& \4 M# E! A* d
  12.   cout<<"小狗的名字是:"<<name<<","<<"年龄是"<<age<<endl;
    7 l0 Q! K0 `$ g! \* B4 ^
  13. }7 {9 C  w. y! C+ R& j; \4 h
  14. };
    # y/ c. R2 ~2 p: r* d% y) ]7 O

  15. 4 p+ Q7 L; ~) I0 E6 B* ~/ W$ Z
  16. int main() {
    ; q" l( T# \6 H' g3 ~# p2 L
  17. /* 从栈中实例化一个对象dog1 */  l: y' I/ N) F* ], H
  18. Dog dog1; 5 k& N' B. x9 s; Y& }! C: x
  19. dog1.name = "旺财"; //为dog1的成员变量赋值
    ! t( Z7 |0 d& ?% c* Z# Q, k1 S. y& s
  20. dog1.age = 2;  //为dog1的成员变量赋值5 _( g2 j6 ]7 d/ _5 O# s  r4 c
  21. dog1.run();   //调用run()方法,打印dog1的相关变量信息4 _" @" i8 A- N  u1 y' |
  22. /* 从堆中实例化对象,使用关键字new的都是从堆中实例化对象 */0 Z( Y* v! z) v% L& h6 @  p
  23. Dog *dog2 = new Dog();
    ( h" H# {4 k3 \, K/ i
  24. if (NULL == dog2) { //从堆中实例化对象需要开辟内存,指针会指向那个内存! o+ j7 I0 P" M! C
  25.   return 0;4 T8 b- R- k$ v8 s. V. c9 _. F
  26. }
    6 F" K+ g# U. _& _: k7 V3 T
  27. dog2->name = "富贵"; //为dog2的成员变量赋值% _; x4 {8 x- a( ?7 L! e8 S+ U
  28. dog2->age = 1;   //为dog2的成员变量赋值% y9 m5 o# S: h* y, ^
  29. dog2->run();   //调用run()方法,打印dog2的相关变量信息, S% q& T0 I' w+ V: E4 J

  30. 9 r7 J6 V$ J) s" Y2 S
  31. delete dog2;   //释放内存
    1 w" U2 _9 [6 A- ]' D, }! P
  32. dog2 = NULL;   //将dog2重新指向NULL  X4 u9 s8 q+ r& _  M
  33. return 0;9 |7 e  b( T7 I# n# D
  34. }
    ; N4 ]4 D: q- J4 |
  35. 执行下面的指令开始编译
    . r- U- {& ~( j9 X, n

  36. , S  L' Y1 O) _7 `* a
  37. g++ class_dog_example.cpp -o class_dog_example7 J9 k0 N9 O2 r* J1 Y
  38. 执行./class_dog_example后结果如下
    : A$ y4 l3 w2 E0 w; h
  39. / s. o+ ?  P. \2 M
  40. 小狗的名字是:旺财,年龄是2
    1 s# ~6 D* @3 t" U
  41. 小狗的名字是:富贵,年龄是1
    5 O# V8 I( o# y/ Y: j. l# D
  42. ⏩ 构造函数与析构函数5 L/ k! I) s7 t& `  [$ Y% f& q
  43. 构造函数在对象实例化时被系统自动调用,仅且调用一次。构造函数的特点如下:
    & |% {" R2 @# g, ?) u9 F
  44. 构造函数必须与类名同名: N  {: L) r% o" ?' i; d6 S' q
  45. " _8 U& Q- T" l$ L- X* s3 E
  46. 可以重载,没有返回类型3 h: A4 y8 w3 o  D7 n6 b

  47. ( w( K- K, g  ~- ]) j& y
  48. 构函数在对象结束其生命周期时系统自动执行。析构函数的特点如下:% U" ]0 W; ^$ h6 x( m
  49. 析构函数的格式为~类名(),调用时释放内存(资源)" j4 v* A5 r" t2 Y4 E2 D
  50. ) F$ \) }2 t3 P
  51. ~类名()不能加参数,没有返回值
    / T+ q: [- d0 q+ s$ M  J$ S4 w
  52. % `* Z4 z$ ]9 S# F, v1 X
  53. 定义类时, 如果没有定义构造函数和析构函数, 编译器就会生成一个构造函数和析构函数, 只是这个构造和析构函数什么事情也不做。当要使用构造函数和析构函数时就需要自己在类里添加
    % m4 `, J4 c$ {+ S; N* M- e

  54. 6 a" n- t: }  B7 V7 O1 Y
  55. /***** structor_example.cpp *****/6 O# `0 l2 H% U' }: {
  56. #include <iostream>
    7 h5 n* [' I7 J4 H% e$ Q
  57. #include <string>, o) _, R! y: I- @2 ^
  58. using namespace std;. G6 Y; o- t7 y; {
  59. * C, n1 |+ q% m/ W% ?
  60. class Dog {  //定义一个类,并在里面写了构造函数和析构函数7 ]$ i& ~" n$ t( R; r# v
  61. public:
    2 \5 P1 @' F" t5 n4 L- g0 }& K
  62. Dog();
    0 [! u' e% n; N1 ~$ G3 |! P; a
  63. ~Dog();
    , S) A7 S' `$ A3 \7 x/ c# e: J' f
  64. };
    ( H9 f, q+ ~+ U, z5 ~1 _
  65. 7 ~2 a  }, M" F8 x1 W0 ~$ n) T
  66. int main() {
    0 A; w9 Z2 e% \# q* \8 U
  67. Dog dog;  //实例化一个dog对象
    - D  i6 @4 o6 M1 G
  68. cout<<"构造与析构函数示例"<<endl;
    ! r7 u9 V8 y1 @, k- {2 ]' @
  69. return 0;
      k1 o7 j, {% t+ C) {. U. t" {
  70. }
    / ~* B* T, @  X1 V; z
  71. //类的函数可在类里实现,也可在类外实现,在类外实现时需要使用“::”
    $ f0 ]- F' l8 O+ |) \: C- \) F
  72. Dog::Dog() {
    - z; |% k2 r+ j3 q, p
  73. cout<<"构造函数执行! "<<endl;6 ~1 Y. D- B& k2 c
  74. }- g# k/ K' C2 x1 ^" \# D4 x* l
  75. 9 V* i' x5 L* w" e% G! M
  76. Dog::~Dog() {: P" q; U7 x8 f/ p1 @
  77. cout<<"析构函数执行! "<<endl;
      ]$ C: z6 z; ?" K: m8 J1 D) l
  78. }
复制代码
执行下面的指令开始编译
  1. g++ structor_example.cpp -o structor_example
      o( x: F+ U" ]& z
复制代码
执行./structor_example后结果如下
  1. 构造函数执行!
    ' _* n, b! r' O+ q& \
  2. 构造与析构函数示例
      P' w, T5 G/ V
  3. 析构函数执行!
复制代码
this指针
每个对象都拥有一个this指针,this指针记录对象的内存地址。this指针是指向类自身数据的指针,简单来说就是指向当前类的当前实例对象。关于类的this指针有以下特点:
* h) h  i& ~9 E1 K$ @+ v
  • this只能在成员函数中使用,全局函数、静态函数都不能使用this
  • this在成员函数的开始前构造,在成员函数的结束后清除
  • this指针会因编译器不同而有不同的放置位置。可能是栈,寄存器或者全局变量

    4 S% s& F2 u) ~0 @- D( z. p# P0 G$ U
  1. /***** this_pointer_example.cpp *****/6 w  O( @7 P# D' }7 c' m' }6 }
  2. #include <iostream>$ j' r8 D- b& l+ y) U: ]2 ~, w
  3. #include <string>' z5 h* ^: Q. \' p( i
  4. using namespace std;
    ! M* n  V! ^  K- `

  5. 2 B" \' o! Y! y9 K* L# S
  6. class Dog {
    ( W( ]: d9 z; k" N* b; d# C( d4 V
  7. public:0 M# @% J: b# b
  8. string name;1 q3 ~) Q( S7 ~
  9. void func();7 P1 s# l/ t1 Q
  10. };
    : _% B/ ~% c, n' W. q

  11. 3 f7 h; \1 e, Z4 b$ N
  12. int main() {
    / I( V7 S7 t0 e  D5 Y
  13. Dog dog;
      }/ Z. c2 J( G% b
  14. dog.func();
    7 y2 l! e7 k- E, L  Y3 |3 u' ]
  15. return 0;
    / ^4 U8 T) f1 O6 D8 ^6 l7 {8 O
  16. }
    0 A+ }- a: j) P% s- F% o
  17. //在类的成员函数里使用了this指针, 并指向了类里的成员name3 n5 b- B, D+ g6 w
  18. void Dog::func() {  V; z$ t: q5 E- B1 M/ H! K
  19. this->name = "旺财";& }+ o2 k+ f* S8 H) E, B7 u# d
  20. cout<<"小狗的名字叫: "<<this->name<<endl;' t  l4 S9 I' z7 P7 Z
  21. }
复制代码
执行下面的指令开始编译
  1. g++ this_pointer_example.cpp -o this_pointer_example
复制代码
执行./this_pointer_example后结果如下
  1. 小狗的名字叫:旺财' m' D/ x! d0 V) S  M5 P# Q
复制代码
4 z% o1 f$ x: A  M# P. R7 K
转载自嵌入式攻城狮

# y9 C7 ?) I3 [; |2 Y

' O8 x" I" ~6 Z/ b% |
赞 收藏 评论0 发布时间:2023-9-25 09:44

举报

0个回答

所属标签

相似技术帖

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版