TouchGFX是一个基于STM32硬件,由C++写成的软件框架,所以有必要对C++基础有一定的了解 一. C++新特性 5 l, [2 H# M4 x; I( V t
C语言里,变量初始化必须在程序的前面,而C++则可以随用随定义。C++也可以直接初始化,比如 int x(100),这样就直接赋值 x=100C++的输入输出方式:以cin和cout代替了C语言里的scanf和printf cout语法形式: - cout << x << endl;
; u5 p: f0 S, C8 A3 p; a - // x 可以是任意数据类型(或表达式)5 l% @: A V* }, B# r- N6 v
- // endl 是换行符,与C里的"\n"效果一样
6 C1 b: L( \4 w" M3 i - cout << x << y << endl; //多个变量的输出
复制代码cin 语法形式: - cin >> x; //x可以是任意数据类型
* b+ K, R5 z- y2 J9 x9 F: x - cin >> x >> y; //多个变量的输入
复制代码C++的命名空间 namespace:using namespace std; - #include <iostream>2 \9 p( C* d0 @. U5 U
- using namespace std;
! Q& p# D5 }5 p3 l$ c7 u5 s - int main(){
* Z1 f1 A ?; B3 e - cout << "Hello, World!" << endl;- A. s- q8 z: ^' ?$ q
- return 0;
3 \5 @8 N$ {2 j- L/ g - }
复制代码上面程序中,头文件要写成iostream,因为是标准输入输出流;带".h"的是非标准输入输出流。using是编译指令,声明当前命名空间的关键词,可理解成使用命名空间std,因为cin和cout都是属于std命名空间的,所以使用时须加上using namespace std,也可以写成std::cin和std::cout,其中 :: 表示作用域 & y, y. n( j4 E8 h
为什么要使用命名空间呢?一些名字易冲突,所以会使用命名空间的方式进行区分,具体来说就是加个前缀。比如C++标准库里面定义了vector容器,自己又写了个vector类,这时名字就冲突了。于是使用标准库里的名字时,都要加上std::的前缀,即std::vector来引用。经常写全名比较繁琐,所以在名字没有冲突的情况下可以添加using namespace std,那么接下去使用标准库里的名字时就可以不用再写std::前缀了 - /***** namespace_example.cpp *****/
* |0 X0 H; L$ j; B( H- y - #include <iostream>' l; x' l& n6 Y% Z9 e) o
- using namespace std;
, r3 J. R3 h4 a$ Y3 r) h1 W! d - namespace A { //自定义命名空间A! k3 p+ Z1 S- [: C. W$ V
- int x = 1;
3 n; ]' Y4 k% O+ N' P/ D* f - void fun() {7 \4 d1 N0 h3 N8 N- e' t+ a% x
- cout<<"A namespace"<<endl;
7 F, T8 O, T8 k, M - }) s+ d4 X* w. D8 @# c G% z
- }
/ z' c% w7 @& R - using namespace A; //声明使用命名空间A
6 ^" h2 |; p& r3 i' Y1 U( Y - int main(){+ q( \% g. X2 @2 [4 W" |! `
- fun(); //声明使用命名空间A后,可直接使用fun()- e7 b% ]" f( i: H$ e- D, x
- A::x = 3; //将A命名空间下的x重新赋值为3" k4 g C* r: n3 |& K
- cout<<A::x<<endl;
' v/ g2 V8 L' X- T - A::fun();
2 `2 M+ N7 V) j9 O& J! y - return 0;% R" U0 d6 K. y8 X
- }
复制代码执行下面的指令开始编译 - g++ namespace_example.cpp -o namespace_example
复制代码执行./namespace_example后结果如下 - A namespace2 E. a" Z2 A4 `& b& C
- 3
6 [' B; P0 @. I; P" f, N9 \6 k - Anamespace
复制代码二. C++面向对象 . N% k( a V6 r6 W
面向对象的三大特征是继承,多态和封装 2.1 类和对象 类是C++的核心特性,通常被称为用户定义的类型。类用于指定对象的形式,包含了数据表示法和用于处理数据的方法。类中的数据和方法称为类的成员,函数在一个类中被称为类的成员。从类中实例化对象分两种方法,一种是从栈中实例化对象,一种是从堆中实例化对象
* V. j: [7 Y/ `2 Z- /***** class_dog_example.cpp *****/
" |3 X) k! ^; |+ p - #include <iostream>+ P; s: i( D0 w& O0 x- Q" `
- #include <string>" \& x7 Y; W2 ]- |# B
- using namespace std;' I0 [, ^' g4 Z! a5 v! Q& P
& V" ?1 H8 N! ~' f- class Dog { //定义一个类
3 h4 O& t" ?2 R" L5 G0 @% S' M# I( { - public: //访问限定符public(公有的),不写的话默认是private' A$ Y& B# ?! ~: [
- string name;
: z e, w; w- h - int age;6 s* F; l1 T% v- P/ G5 J
-
( d) K- q7 S+ e5 k - void run() { //定义一个方法+ t$ D: y7 Q# N! c8 K0 L; T
- cout<<"小狗的名字是:"<<name<<","<<"年龄是"<<age<<endl;3 o( Z0 I s. d3 s9 T8 p0 M
- } D1 t/ T- V" g
- };
$ ^, R$ z# m% O7 c# y
/ B9 ]1 D7 q1 D9 x; d' M- int main() {, X% n; X: J( B; W' v6 _
- /* 从栈中实例化一个对象dog1 */, @8 t. r* N s" B% _+ H
- Dog dog1;
" U: F4 s" L) d; E/ J - dog1.name = "旺财"; //为dog1的成员变量赋值/ E; p. V- N+ g# a" ?
- dog1.age = 2; //为dog1的成员变量赋值
1 @0 ?$ ?2 J/ H - dog1.run(); //调用run()方法,打印dog1的相关变量信息
. c/ q& @" k1 ~ - /* 从堆中实例化对象,使用关键字new的都是从堆中实例化对象 */
7 T! ?! ? v) _4 K6 ?3 S - Dog *dog2 = new Dog();
9 `2 W0 |5 \# Z4 _+ Y - if (NULL == dog2) { //从堆中实例化对象需要开辟内存,指针会指向那个内存
5 c7 H4 o" p. j/ n' ^6 v9 q - return 0;
) w8 ]6 L! u3 \ - }
2 R- o4 b" u+ L3 B+ @0 f$ n5 j - dog2->name = "富贵"; //为dog2的成员变量赋值
- Z! [+ Z2 p" p+ {$ z - dog2->age = 1; //为dog2的成员变量赋值- e0 x- ~6 u* |4 t4 J% i# n
- dog2->run(); //调用run()方法,打印dog2的相关变量信息0 j4 X- M6 [' a. j/ v, N
, ^: U& t' ?( T) H4 @, A- delete dog2; //释放内存5 M7 A7 t+ |- v: A9 n: W
- dog2 = NULL; //将dog2重新指向NULL. y9 Q" S* n! a1 a
- return 0;/ M8 y( b3 }4 l
- }
5 z% p( t& V$ k6 E3 }# R* |/ Z - 执行下面的指令开始编译
5 W0 X; k4 y# a& A: k; q9 _# x
8 g3 S1 o$ }8 ^7 _& g- g++ class_dog_example.cpp -o class_dog_example. q3 p5 H# Q, R* P2 K0 m! ]
- 执行./class_dog_example后结果如下; H7 _ b6 @8 b" C/ w
- # @) A* j6 @+ u2 Q
- 小狗的名字是:旺财,年龄是2
- I" _ m: a6 v3 l2 f - 小狗的名字是:富贵,年龄是1; @( ]( A f! h$ L; J
- ⏩ 构造函数与析构函数
, e4 j# X. r. c3 t/ ? - 构造函数在对象实例化时被系统自动调用,仅且调用一次。构造函数的特点如下:) V7 B# w9 J- X
- 构造函数必须与类名同名
3 O/ m f/ R; j& i, {) ?. C
, X2 J! z+ X+ c- 可以重载,没有返回类型
1 e5 c8 V0 `: M
6 Q/ {# x; e+ S( t H Y$ h/ x- 构函数在对象结束其生命周期时系统自动执行。析构函数的特点如下:! G. x! r% D9 J1 M# a1 l! e- w
- 析构函数的格式为~类名(),调用时释放内存(资源)( k( W$ f1 w9 |# G+ q( |% \
- # v4 Y5 X# @9 O+ w" ~
- ~类名()不能加参数,没有返回值
. U1 j. L3 ]3 z! i1 t. [2 B$ {7 f; A5 O
+ `8 O5 s& o0 c! t- 定义类时, 如果没有定义构造函数和析构函数, 编译器就会生成一个构造函数和析构函数, 只是这个构造和析构函数什么事情也不做。当要使用构造函数和析构函数时就需要自己在类里添加, F4 ?: j9 O A0 e7 D5 n
- ) S' t# p3 P$ A3 |* z; I; o
- /***** structor_example.cpp *****/
W4 o3 l+ a0 r - #include <iostream>
& V5 f& x2 Q* S% f; u( J - #include <string>
$ h: R) i C; E$ d7 b2 i - using namespace std;
9 J/ m' t9 j* B( i2 X/ o - 5 s, ]4 q/ R! a/ t: }6 U& d; L
- class Dog { //定义一个类,并在里面写了构造函数和析构函数
3 o; ?0 u/ \9 w5 e% `% e' q1 S - public:- ~ I P8 y+ Y: q
- Dog();
" u$ c# @* P0 h" H. T5 D - ~Dog();
$ a3 d |5 e& f' G+ Q1 ~; l - };
' F6 r( C& J) J* b! h3 C
) T1 P3 A1 p7 J. _3 O/ ?1 M- int main() {4 l2 w- y0 f( }( N" X
- Dog dog; //实例化一个dog对象
1 {# Q2 B% `6 \$ Y, { - cout<<"构造与析构函数示例"<<endl;
7 T+ s$ u* y2 Z ^ J' e) t - return 0;1 k( _! }# v7 W
- }
$ q/ v: s9 x; L5 Y8 I- ~ - //类的函数可在类里实现,也可在类外实现,在类外实现时需要使用“::”/ V0 ~$ F- H [. O S+ `
- Dog::Dog() {, b {' V0 y/ u8 ]
- cout<<"构造函数执行! "<<endl;
0 `* l L1 }* Y( ^0 R - }* [4 f4 B& h$ b- r7 F! Q# _
; `( t! a. }& V7 H ]- Dog::~Dog() {' D, ]& N# ?: W6 p% b; a& `" Z
- cout<<"析构函数执行! "<<endl;
- l7 _, J; A. z' h0 W. ] n+ c/ j - }
复制代码执行下面的指令开始编译 - g++ structor_example.cpp -o structor_example
" E, s/ n6 j: |% h( e
复制代码执行./structor_example后结果如下 - 构造函数执行!
X( f: ^9 R) w* [ - 构造与析构函数示例
3 f; W, ]2 U& | - 析构函数执行!
复制代码this指针 每个对象都拥有一个this指针,this指针记录对象的内存地址。this指针是指向类自身数据的指针,简单来说就是指向当前类的当前实例对象。关于类的this指针有以下特点: % v5 g9 ^5 l, Z/ ]6 O: K* k
this只能在成员函数中使用,全局函数、静态函数都不能使用this this在成员函数的开始前构造,在成员函数的结束后清除 this指针会因编译器不同而有不同的放置位置。可能是栈,寄存器或者全局变量
$ T) K4 L7 ]9 N6 E
- /***** this_pointer_example.cpp *****/% c7 f% N. A* w) X. ^5 E
- #include <iostream>
/ U q& f8 J) G- X2 G- X' Z - #include <string>5 `) O) _3 l; S9 G+ ?
- using namespace std;5 |4 A/ A+ i- Q/ x6 Q
- 3 p0 c7 p" |& G+ P: m7 F: |
- class Dog {
& r7 N; x* A. F' K1 m: V" c( x - public:
% m: k: q" _0 X$ i+ M1 u) ~( Q9 q - string name;( t2 L3 |6 m& d3 `( P0 c
- void func();; ^: b* S- `7 q6 I, M
- };
: u" R( S* _6 V H2 u/ ~2 u H3 j - ( h% N+ E/ g/ n2 Z9 O7 Z* C# z! q
- int main() {- A U4 T% {" e2 A, d
- Dog dog;
; U1 z; Q% J1 B# V7 W - dog.func();$ i" @" ?9 d1 G+ R. P( r4 R& e$ J
- return 0;* V! m2 ~# [* q2 L
- } J0 E4 z* u% Y- d' R, L
- //在类的成员函数里使用了this指针, 并指向了类里的成员name7 ]( A) ]8 I1 ?0 v: x
- void Dog::func() {$ H) j- [( u l. E* O4 d. a
- this->name = "旺财";
- L6 h2 j( z. } - cout<<"小狗的名字叫: "<<this->name<<endl;" h9 j R" o/ \
- }
复制代码执行下面的指令开始编译 - g++ this_pointer_example.cpp -o this_pointer_example
复制代码执行./this_pointer_example后结果如下 - 小狗的名字叫:旺财5 Q+ t/ z9 }& W% l% a9 J
复制代码
$ X! ]3 k# _# r6 x& ?) ?' V 转载自嵌入式攻城狮 0 b# l. P, }5 g* ?1 W5 V, G
* J; g7 _' X8 @( ~) e* S% |# P' c
|