|
TouchGFX是一个基于STM32硬件,由C++写成的软件框架,所以有必要对C++基础有一定的了解 一. C++新特性 % m1 p4 A: l5 [8 Q. U. m
C语言里,变量初始化必须在程序的前面,而C++则可以随用随定义。C++也可以直接初始化,比如 int x(100),这样就直接赋值 x=100C++的输入输出方式:以cin和cout代替了C语言里的scanf和printf cout语法形式: - cout << x << endl;! }; I2 Q6 ~- b2 S2 }+ k
- // x 可以是任意数据类型(或表达式)
# x1 E1 G x! l7 x - // endl 是换行符,与C里的"\n"效果一样9 A& @: D0 S( E& |9 p- R. b4 q
- cout << x << y << endl; //多个变量的输出
复制代码cin 语法形式: - cin >> x; //x可以是任意数据类型
! ^( Z! i, w9 l2 g5 M1 s" Y - cin >> x >> y; //多个变量的输入
复制代码C++的命名空间 namespace:using namespace std; - #include <iostream>
2 a% c/ A) T: a - using namespace std;: a% Y) C$ |& D y) E$ E
- int main(){
, E u7 |! `8 _# X% P" ^! C - cout << "Hello, World!" << endl;, {0 i+ X# o9 E) Y# D, D, g5 i' I
- return 0;
- E9 S/ M: o. Q - }
复制代码上面程序中,头文件要写成iostream,因为是标准输入输出流;带".h"的是非标准输入输出流。using是编译指令,声明当前命名空间的关键词,可理解成使用命名空间std,因为cin和cout都是属于std命名空间的,所以使用时须加上using namespace std,也可以写成std::cin和std::cout,其中 :: 表示作用域
$ N: T$ A* ~& N/ Y5 ~7 V6 T为什么要使用命名空间呢?一些名字易冲突,所以会使用命名空间的方式进行区分,具体来说就是加个前缀。比如C++标准库里面定义了vector容器,自己又写了个vector类,这时名字就冲突了。于是使用标准库里的名字时,都要加上std::的前缀,即std::vector来引用。经常写全名比较繁琐,所以在名字没有冲突的情况下可以添加using namespace std,那么接下去使用标准库里的名字时就可以不用再写std::前缀了 - /***** namespace_example.cpp *****/' [2 n6 O! T1 ?/ U' J
- #include <iostream>
& t7 p7 M [- | a" z& F0 r' D - using namespace std;
a9 G5 d6 ?) r, u8 D* v' ?- t - namespace A { //自定义命名空间A! U+ l) ^0 {$ U& F, }
- int x = 1;* \8 r1 B/ {+ D) h9 D
- void fun() {
$ R3 r5 f) n! y8 Y - cout<<"A namespace"<<endl;* L9 e2 Z8 Q: M& T
- }
4 X6 C& ]4 b$ w7 h" K( G - }
: m1 M# N9 F% L$ q* b/ e - using namespace A; //声明使用命名空间A
0 V; q1 d; k" ? - int main(){. B: a# Q, d$ A0 l/ L/ i
- fun(); //声明使用命名空间A后,可直接使用fun()# j m3 O; x" O/ @
- A::x = 3; //将A命名空间下的x重新赋值为3, ?2 y, @7 B$ f* [8 a+ D' z
- cout<<A::x<<endl;7 F7 o& G" B4 L" Z3 A
- A::fun();, R0 G& g# n8 Q
- return 0;. i; `0 H: R; M- ^
- }
复制代码执行下面的指令开始编译 - g++ namespace_example.cpp -o namespace_example
复制代码执行./namespace_example后结果如下 - A namespace
4 ~' {$ k7 o; D; `3 ~) [ - 39 s5 U N! ^% o
- Anamespace
复制代码二. C++面向对象
, ~. k2 W+ I8 C
面向对象的三大特征是继承,多态和封装 2.1 类和对象 类是C++的核心特性,通常被称为用户定义的类型。类用于指定对象的形式,包含了数据表示法和用于处理数据的方法。类中的数据和方法称为类的成员,函数在一个类中被称为类的成员。从类中实例化对象分两种方法,一种是从栈中实例化对象,一种是从堆中实例化对象 ' k- [% X0 u0 D! y @7 S3 f
- /***** class_dog_example.cpp *****/
4 z3 {/ V6 b) b, g" {" u0 y* ? - #include <iostream>
3 H' T. T( H5 I7 |) |+ o2 }- [ - #include <string>9 K7 D6 Y* b8 U1 M
- using namespace std;5 Y! L+ m2 h* `. Z! N% f/ x
* ?6 @4 o0 w+ ?- u4 n ^6 ?3 w- class Dog { //定义一个类
) f* C0 h+ m8 r& a5 ^6 N - public: //访问限定符public(公有的),不写的话默认是private6 j& `% v5 ?- J) R2 f
- string name;( Z6 W/ P4 O$ l5 L: N
- int age;
, x9 y* `/ l1 W& [ - 2 O. O3 G+ F1 s" B, z' K% U
- void run() { //定义一个方法
' Y7 E0 c# r9 v* z2 G" W - cout<<"小狗的名字是:"<<name<<","<<"年龄是"<<age<<endl;! \; H2 ^6 X7 J1 J* K& c# ]
- }
. `# H. W0 W/ R# C+ U: v - };
- _5 w8 K1 K4 K1 Z( f - ; a& f! I. u C; A1 p8 q7 S( Y4 j5 ~: j
- int main() {! s. L6 Z$ U; q1 H) D. ^
- /* 从栈中实例化一个对象dog1 */. E" X6 ]" h+ Q8 n# A$ G$ a* Q
- Dog dog1;
% q& A8 N$ N1 a+ [( {& c6 m+ w7 W - dog1.name = "旺财"; //为dog1的成员变量赋值
. F6 E. ~1 K) d3 t# Z# l) \ - dog1.age = 2; //为dog1的成员变量赋值( u! E8 c3 m! r" U2 R- r! S
- dog1.run(); //调用run()方法,打印dog1的相关变量信息
4 ]6 ^ D7 g2 R7 p' ^+ r - /* 从堆中实例化对象,使用关键字new的都是从堆中实例化对象 */( R9 u( l# ^5 D1 i
- Dog *dog2 = new Dog();
+ a& l. d) I: A7 `! g2 s9 K0 g - if (NULL == dog2) { //从堆中实例化对象需要开辟内存,指针会指向那个内存
- n0 l- D7 T' B5 X! v6 r - return 0;% a5 l' J! A7 J3 h# t) G5 j
- }
6 A5 S3 l+ W4 S9 W: u5 ]; p - dog2->name = "富贵"; //为dog2的成员变量赋值2 o8 q% o/ G) w) h2 U# ]
- dog2->age = 1; //为dog2的成员变量赋值6 X! `0 @+ g3 S) Y, W/ z. `0 R: E9 f# G
- dog2->run(); //调用run()方法,打印dog2的相关变量信息
' R5 }) h: _- Z; t9 [+ r V
6 E5 y, H6 f; J+ u* e- delete dog2; //释放内存
5 y- _- J" {" M+ J2 V - dog2 = NULL; //将dog2重新指向NULL
9 X( U2 m! c p q; G3 M6 W* j: C - return 0;# h+ o: Z! i* F2 p/ `
- }
; U- X4 I* _6 O. } - 执行下面的指令开始编译" N0 w2 H8 |5 x! Y2 }' z
- % V% N& i: l! o, K
- g++ class_dog_example.cpp -o class_dog_example
: t6 j; X, L5 F% R f- J - 执行./class_dog_example后结果如下
4 j/ J3 v& B6 h" d- d - 4 O6 ]3 M7 e/ ?( s, y3 B+ b, {
- 小狗的名字是:旺财,年龄是25 X& i9 F: ~) v% c
- 小狗的名字是:富贵,年龄是1, A. H* I" c: Z6 M+ \# N
- ⏩ 构造函数与析构函数
. _8 z- Y5 g% t2 Y% ? - 构造函数在对象实例化时被系统自动调用,仅且调用一次。构造函数的特点如下:
# t; K6 _4 a6 K2 S) `$ Q1 ~ - 构造函数必须与类名同名$ C9 X' }# x3 U& ~
- X a+ ]4 j7 Y
- 可以重载,没有返回类型
8 f) O- D$ c2 J% e" C Y
4 x2 y6 ^ e' V6 [- 构函数在对象结束其生命周期时系统自动执行。析构函数的特点如下:
+ c# N2 m6 H$ K. t a* b - 析构函数的格式为~类名(),调用时释放内存(资源)
- ?0 d: } Z% L+ z" Z- I - 4 I4 ~& P. s ]- k# y h
- ~类名()不能加参数,没有返回值
6 ^8 q' j+ ?' F; g
/ L/ {. k, n6 R' V; `- 定义类时, 如果没有定义构造函数和析构函数, 编译器就会生成一个构造函数和析构函数, 只是这个构造和析构函数什么事情也不做。当要使用构造函数和析构函数时就需要自己在类里添加
' Y; w! z: V6 y: {( E+ A/ ~ - g! O. Q: P T( t5 N
- /***** structor_example.cpp *****/
( [% e& k8 \8 C9 r9 \ - #include <iostream>+ a9 d, g* e& k) e4 m) i
- #include <string>. p9 F/ W& |& O
- using namespace std;
! V1 I7 t" `8 B& K
- w/ `7 B$ u0 |- R' W" X- class Dog { //定义一个类,并在里面写了构造函数和析构函数' z6 N0 X2 L8 ?1 R [8 c1 y3 O2 t
- public:
; F& U" n+ K: ?) l0 v' [1 T - Dog();8 e5 _# A5 m; T# U* V
- ~Dog();
$ \. \# @# _, h. h$ }# o - };9 Z r5 g. l' J/ [2 I7 o: Y
- ' \) ^$ }4 G$ Z1 A( ^
- int main() {
& {8 `: t/ D8 g/ }$ l1 Q/ _ - Dog dog; //实例化一个dog对象! |4 Z- V( p) C- }8 F
- cout<<"构造与析构函数示例"<<endl;+ @$ j& d1 s* g) Y
- return 0;
8 r: }+ ]* ]4 K E - }0 q" G- Q# {, m
- //类的函数可在类里实现,也可在类外实现,在类外实现时需要使用“::”
# [0 @$ q$ T K P7 w - Dog::Dog() {! c) ^5 z, w; ]9 K; I+ Z# X! O
- cout<<"构造函数执行! "<<endl;4 n2 k* s# e2 J/ g
- }
. f3 q8 s* {" T4 d
2 O2 Z' [, g2 _$ |! T+ B1 O8 C5 q- Dog::~Dog() {
2 X5 b1 f/ S# }) V) } Z - cout<<"析构函数执行! "<<endl;
2 m$ H' t: ~+ X% A, a- e$ u - }
复制代码执行下面的指令开始编译 - g++ structor_example.cpp -o structor_example
" ~+ b7 O: w2 X' N
复制代码执行./structor_example后结果如下 - 构造函数执行!% l( \# W t2 G
- 构造与析构函数示例
, j& B' Z. I) l' s - 析构函数执行!
复制代码this指针 每个对象都拥有一个this指针,this指针记录对象的内存地址。this指针是指向类自身数据的指针,简单来说就是指向当前类的当前实例对象。关于类的this指针有以下特点: $ l2 B Y+ m, D. y, f4 i) ]# m
this只能在成员函数中使用,全局函数、静态函数都不能使用this this在成员函数的开始前构造,在成员函数的结束后清除 this指针会因编译器不同而有不同的放置位置。可能是栈,寄存器或者全局变量 # m' u; ?7 z: b5 _: R; x
- /***** this_pointer_example.cpp *****// O" v; D8 k% k$ z+ ]5 n% v
- #include <iostream>; o M0 [5 r" r) _- b/ x" C
- #include <string>
+ ?2 J4 P* D$ G( y - using namespace std;
/ Q+ q3 `+ F" |& w - 8 \! t. |9 x# v. v
- class Dog {
$ e6 e5 o3 x2 l* g - public:9 p) j8 S% a* ~$ W T N
- string name;0 H! S; @" [$ S& l/ w4 G
- void func();
8 b, c$ m# N8 A; M - };
8 y, I2 T3 |% V$ r! R - s6 o; K8 ?0 E8 z! P ?
- int main() {
# r; t$ L" x- |% Z - Dog dog;
3 ]2 U- m1 g8 F7 Z3 q- w9 f - dog.func();5 Q4 `. M' u; K5 a' I' a5 n
- return 0;# {( \ Z8 q3 C
- }
- v: \3 Z, j* j- a - //在类的成员函数里使用了this指针, 并指向了类里的成员name+ T% r) X8 N1 W# r) U
- void Dog::func() {% r! F# ]2 ?0 E1 T: b+ y* [
- this->name = "旺财";
6 U, A$ V* i6 B1 U' D - cout<<"小狗的名字叫: "<<this->name<<endl;
- o6 v6 w7 M) \, p, R9 \9 m7 Z - }
复制代码执行下面的指令开始编译 - g++ this_pointer_example.cpp -o this_pointer_example
复制代码执行./this_pointer_example后结果如下 S& S! W3 ]5 D& O4 X3 ]
转载自嵌入式攻城狮 7 H1 @2 D* k/ G# D2 F7 Z6 j
! i. }& P' l q* u
|