TouchGFX是一个基于STM32硬件,由C++写成的软件框架,所以有必要对C++基础有一定的了解 一. C++新特性
- ~) s! k$ ^8 w; L
C语言里,变量初始化必须在程序的前面,而C++则可以随用随定义。C++也可以直接初始化,比如 int x(100),这样就直接赋值 x=100C++的输入输出方式:以cin和cout代替了C语言里的scanf和printf cout语法形式: - cout << x << endl;- z# J2 C2 `- x" j Z
- // x 可以是任意数据类型(或表达式)
M, s4 g o! D- m - // endl 是换行符,与C里的"\n"效果一样
, [6 i3 ~ C8 {4 S2 { - cout << x << y << endl; //多个变量的输出
复制代码cin 语法形式: - cin >> x; //x可以是任意数据类型
! D6 h3 V( k. M) J* p' m - cin >> x >> y; //多个变量的输入
复制代码C++的命名空间 namespace:using namespace std; - #include <iostream>' l+ m* x i% F' J
- using namespace std;
7 m2 s' n$ Y0 x6 `+ ` Q - int main(){
8 ^* f5 j3 Y4 b& T9 c/ H - cout << "Hello, World!" << endl;
! _1 X8 e8 I! f# ~# x0 Y! L( ~ - return 0;% u# x& C& H6 m4 C5 ?. C, [# N# Z
- }
复制代码上面程序中,头文件要写成iostream,因为是标准输入输出流;带".h"的是非标准输入输出流。using是编译指令,声明当前命名空间的关键词,可理解成使用命名空间std,因为cin和cout都是属于std命名空间的,所以使用时须加上using namespace std,也可以写成std::cin和std::cout,其中 :: 表示作用域 $ m1 L% w3 k; w- g: G j
为什么要使用命名空间呢?一些名字易冲突,所以会使用命名空间的方式进行区分,具体来说就是加个前缀。比如C++标准库里面定义了vector容器,自己又写了个vector类,这时名字就冲突了。于是使用标准库里的名字时,都要加上std::的前缀,即std::vector来引用。经常写全名比较繁琐,所以在名字没有冲突的情况下可以添加using namespace std,那么接下去使用标准库里的名字时就可以不用再写std::前缀了 - /***** namespace_example.cpp *****/
0 ~, U/ J3 [1 s* F* p - #include <iostream>! ]. K7 v7 ~) K3 T# K9 Z
- using namespace std; [1 I. `: q7 Q. A4 o2 y8 S
- namespace A { //自定义命名空间A1 v& ]% I8 a) s1 [
- int x = 1;
: z2 J* L: s T" Y* @ - void fun() {8 V N& w1 V3 P1 z
- cout<<"A namespace"<<endl;
% b- M( L5 k/ E - }& d8 y* E) ? ?, s
- }6 m) }/ P2 `, z' l
- using namespace A; //声明使用命名空间A6 D( Y$ R$ O* v8 m- n% a- _
- int main(){
' x1 l8 n, q4 p% m& d6 b - fun(); //声明使用命名空间A后,可直接使用fun()& D. n8 V$ e# b+ K' I7 h
- A::x = 3; //将A命名空间下的x重新赋值为3) _" Y0 n! h$ @. j: L5 _
- cout<<A::x<<endl;
% g$ v' C+ a( h# ~" A5 B - A::fun();) V. `! }6 k9 E( X
- return 0;9 J* O3 H/ k4 s, N2 C* C7 c3 K
- }
复制代码执行下面的指令开始编译 - g++ namespace_example.cpp -o namespace_example
复制代码执行./namespace_example后结果如下 - A namespace3 _/ m5 o* M# B4 s x' E, u( x) f
- 3
! n4 X$ c7 B+ s1 b( Z - Anamespace
复制代码二. C++面向对象 3 [% ?3 q ]: L4 R1 p3 x% g) Z
面向对象的三大特征是继承,多态和封装 2.1 类和对象 类是C++的核心特性,通常被称为用户定义的类型。类用于指定对象的形式,包含了数据表示法和用于处理数据的方法。类中的数据和方法称为类的成员,函数在一个类中被称为类的成员。从类中实例化对象分两种方法,一种是从栈中实例化对象,一种是从堆中实例化对象
; w2 N& T3 n m& B. \* L# k- /***** class_dog_example.cpp *****/
$ c, g! e+ {3 b6 M+ G' q2 ~0 L( i - #include <iostream>
7 G% k6 {5 V! Y% j" G - #include <string>8 }3 }% w) O% F1 Q3 R: R7 G
- using namespace std;
) a* h, m' t+ l# C - , t; z4 s; ~2 s
- class Dog { //定义一个类
2 q$ J8 h. Z1 \3 } - public: //访问限定符public(公有的),不写的话默认是private1 Z/ T& E, D4 V
- string name;
- H" ~5 K- P' w( z8 |5 p4 x, p- [ - int age;6 w+ ?3 ] {: h9 {+ @6 ]8 x
- J" T: ~. H) K% w- l
- void run() { //定义一个方法
* O" A8 [) f: ^# v! k: b - cout<<"小狗的名字是:"<<name<<","<<"年龄是"<<age<<endl;! ~% i5 w* t; }. o2 ?
- }: B$ _2 w; q; @( B6 g' E+ y
- };
$ D1 c1 d' e7 E& p - 2 H; }7 |( ?. }" ?4 ~
- int main() {
9 N" f( n# e) k) R - /* 从栈中实例化一个对象dog1 */8 U# ~4 N6 x5 F+ L
- Dog dog1; 4 G0 |: ~! j- \7 n2 A
- dog1.name = "旺财"; //为dog1的成员变量赋值: F8 o% f1 f m5 d! p( ~
- dog1.age = 2; //为dog1的成员变量赋值6 s( a3 b5 `9 g/ @
- dog1.run(); //调用run()方法,打印dog1的相关变量信息
% k; z3 {8 s/ T- h7 t! ] - /* 从堆中实例化对象,使用关键字new的都是从堆中实例化对象 */1 Y) c8 [7 |+ Z1 P8 e0 ?' t
- Dog *dog2 = new Dog();
2 W8 Q* P3 Z* [* C7 K1 R+ q - if (NULL == dog2) { //从堆中实例化对象需要开辟内存,指针会指向那个内存
! w( m% j4 b& F1 N - return 0;% Y, ~; r" G' Y
- }
5 D9 V! u( }4 N; V4 f! L; r - dog2->name = "富贵"; //为dog2的成员变量赋值
) k/ ]5 A+ X4 E, F2 R( R+ s - dog2->age = 1; //为dog2的成员变量赋值& Z; w1 e) z2 p# |
- dog2->run(); //调用run()方法,打印dog2的相关变量信息- K+ v; \! T; n+ Q
5 D+ i- q" y, F& h- delete dog2; //释放内存0 f5 ?; F& |- U9 I' y& x. h
- dog2 = NULL; //将dog2重新指向NULL0 U; O+ r! B( Y
- return 0;8 p7 G! d; J+ c# f3 r9 T. x& j
- }
( ?- ?% |0 a& N# O - 执行下面的指令开始编译" M: g0 ]# d& m1 q6 ^/ t4 X
- ( b4 W" X. ` v' m4 }2 h
- g++ class_dog_example.cpp -o class_dog_example
- y* j4 p% v, R9 U }# D - 执行./class_dog_example后结果如下
* ^% {, e5 X6 @+ o7 D: ^5 v; ?- w
, ?& s) T, a- L; {; ^1 O- 小狗的名字是:旺财,年龄是2
) e+ z" O! ` a0 o) t' C. \ - 小狗的名字是:富贵,年龄是1 ?6 o. C. Z6 e
- ⏩ 构造函数与析构函数
, y: h9 U& @' X' ~: ~/ [ - 构造函数在对象实例化时被系统自动调用,仅且调用一次。构造函数的特点如下:4 h2 t, j4 q; n/ a
- 构造函数必须与类名同名
* H+ U2 y" o9 |9 K - : a9 n0 p) X+ ~8 C) O7 b7 B9 v1 N
- 可以重载,没有返回类型
% b! N' B. o# T0 U - 9 R+ T6 W5 j: K C5 b0 ?
- 构函数在对象结束其生命周期时系统自动执行。析构函数的特点如下:
9 W( ?" o/ M& ?7 I% _( b5 s$ v - 析构函数的格式为~类名(),调用时释放内存(资源)" X( U* y" z- W4 L: [0 F1 j
3 k. f* ^9 c' c3 o4 [- ]- ~类名()不能加参数,没有返回值- o: c3 z% M. t: ^- f2 i- V! I& T& Y
; _! l5 E" Y, w6 o9 N7 ]. q, M3 J) p- 定义类时, 如果没有定义构造函数和析构函数, 编译器就会生成一个构造函数和析构函数, 只是这个构造和析构函数什么事情也不做。当要使用构造函数和析构函数时就需要自己在类里添加5 C6 T( Q/ C( m' V! I" N" [
( H: O# Z& i ?% y- /***** structor_example.cpp *****/6 }$ i" y. e* s- G" I0 f1 o0 a
- #include <iostream>
5 Z7 b8 V, r: C9 w2 d - #include <string>
% `9 e" ]! y/ V# X' B/ C* Z - using namespace std;
/ @& u/ \* N0 s7 A4 F9 e: o: o T' {
]. u9 I" e) z- y) T- class Dog { //定义一个类,并在里面写了构造函数和析构函数) J* ]0 i6 [ x: G' D. k) [
- public:: l2 A* E( t6 K
- Dog();; K% R2 w- z* |' {9 ^0 h& w
- ~Dog();
9 s6 w* w& S& d - };
8 |4 D- } j( p! g
* d$ d6 {7 }/ p. d1 I5 Z/ V- int main() {3 f$ P2 W8 t/ v) ]
- Dog dog; //实例化一个dog对象+ P% i6 [) y, T1 e) O& ?
- cout<<"构造与析构函数示例"<<endl;
6 Z) i, @) ~1 c4 N2 M% R! W/ i8 R - return 0;
; G( s7 Z d% ` - }
" [/ S: n$ p7 C; U1 J - //类的函数可在类里实现,也可在类外实现,在类外实现时需要使用“::”. E5 X2 u7 n. I Y3 x6 W0 G
- Dog::Dog() {0 N( H/ u- k1 T( W) n0 Z) C( q
- cout<<"构造函数执行! "<<endl;
1 z: N C7 Y' Q - }: y3 g9 B4 u' |, T7 \
) |- z/ V/ p- ]0 [( r- Dog::~Dog() {2 R, |' L8 p1 m( i7 e x2 u# y
- cout<<"析构函数执行! "<<endl;
G8 V0 { @# d; _2 v4 p( Y - }
复制代码执行下面的指令开始编译 - g++ structor_example.cpp -o structor_example
$ G; F* b' t0 E+ u# x! E
复制代码执行./structor_example后结果如下 - 构造函数执行!( m/ W3 M \1 W: q$ |
- 构造与析构函数示例
$ {! Z$ w) |( b5 A1 x9 u! L - 析构函数执行!
复制代码this指针 每个对象都拥有一个this指针,this指针记录对象的内存地址。this指针是指向类自身数据的指针,简单来说就是指向当前类的当前实例对象。关于类的this指针有以下特点: 9 p2 R7 T! y/ o% q/ Y# H
this只能在成员函数中使用,全局函数、静态函数都不能使用this this在成员函数的开始前构造,在成员函数的结束后清除 this指针会因编译器不同而有不同的放置位置。可能是栈,寄存器或者全局变量 5 G+ {% X p3 j; I! K6 T( @9 x
- /***** this_pointer_example.cpp *****/
3 V) h5 a0 i* Y& n5 R - #include <iostream>
2 X0 d( x& u2 z - #include <string>0 X" f! F& z2 W* V% z9 F
- using namespace std;+ P9 U- ^) C$ T7 B R; O& y
* j2 G) x6 |- I9 I9 |- class Dog {
2 [) R# P! W/ J" |) B4 g# A - public:1 b: z" L- { Q! c9 [
- string name;* ^. _; M/ E! p$ ]; f2 F
- void func();0 Z' h9 }/ Y' f+ S
- };
7 ]6 M6 H; Q( j0 O/ \ - + U$ R# n8 w/ g; U5 J3 o/ O' p2 y
- int main() {
8 O" Y3 ^: v, H! I - Dog dog;" C( a1 R6 s+ i* H
- dog.func(); a* Z" _6 J+ `
- return 0;
' [( \ A) J8 Q2 O& Z - }
6 S6 M1 j" T9 Y" B$ {7 y - //在类的成员函数里使用了this指针, 并指向了类里的成员name" K$ X. z1 P/ W. X) O
- void Dog::func() {1 e/ r# H; S. S. ?' \( ?* z8 W
- this->name = "旺财";' e0 L/ k) ~$ G [1 j1 F
- cout<<"小狗的名字叫: "<<this->name<<endl;) b& P w) \$ \. t) y2 l% h5 ]
- }
复制代码执行下面的指令开始编译 - g++ this_pointer_example.cpp -o this_pointer_example
复制代码执行./this_pointer_example后结果如下 - 小狗的名字叫:旺财
! ]# W# `; X' \" X% ?
复制代码
7 g4 F- ?( c" ]8 F0 p7 ` 转载自嵌入式攻城狮
. g: p4 e5 F, M8 p; Z. F
1 @' s2 s$ R7 a" u/ x" b3 G |