|
TouchGFX是一个基于STM32硬件,由C++写成的软件框架,所以有必要对C++基础有一定的了解 一. C++新特性
9 }. `0 T* ]" W" _4 v
C语言里,变量初始化必须在程序的前面,而C++则可以随用随定义。C++也可以直接初始化,比如 int x(100),这样就直接赋值 x=100C++的输入输出方式:以cin和cout代替了C语言里的scanf和printf cout语法形式: - cout << x << endl;
6 P! P E* T* i% r: D - // x 可以是任意数据类型(或表达式)
. x: n6 ~8 m) |4 X9 o. ? - // endl 是换行符,与C里的"\n"效果一样6 X/ _* a c6 J) n0 n( y
- cout << x << y << endl; //多个变量的输出
复制代码cin 语法形式: - cin >> x; //x可以是任意数据类型' J+ K/ \2 J+ d5 y3 g! _1 n8 J
- cin >> x >> y; //多个变量的输入
复制代码C++的命名空间 namespace:using namespace std; - #include <iostream>( M2 T" C3 j, p% \/ P. C7 x9 K
- using namespace std;
! s; m2 Q! l6 X f - int main(){$ Y1 z+ S9 o' c
- cout << "Hello, World!" << endl;
- S* d r& M9 z0 c+ Q/ ~7 x - return 0;
7 S$ M1 _: M4 i: L9 e9 t1 x, g: O( I; |3 } - }
复制代码上面程序中,头文件要写成iostream,因为是标准输入输出流;带".h"的是非标准输入输出流。using是编译指令,声明当前命名空间的关键词,可理解成使用命名空间std,因为cin和cout都是属于std命名空间的,所以使用时须加上using namespace std,也可以写成std::cin和std::cout,其中 :: 表示作用域
) [5 Z- A( G3 |( d* n! O4 W% @: y9 Y为什么要使用命名空间呢?一些名字易冲突,所以会使用命名空间的方式进行区分,具体来说就是加个前缀。比如C++标准库里面定义了vector容器,自己又写了个vector类,这时名字就冲突了。于是使用标准库里的名字时,都要加上std::的前缀,即std::vector来引用。经常写全名比较繁琐,所以在名字没有冲突的情况下可以添加using namespace std,那么接下去使用标准库里的名字时就可以不用再写std::前缀了 - /***** namespace_example.cpp *****/
5 h i+ \' i) l. ` K4 F# d. G - #include <iostream>/ z, \" x8 F# H! z* u9 k4 `
- using namespace std;
l6 Q; m% F& t0 ]% h3 p( b - namespace A { //自定义命名空间A% w" O' E& C t2 ]5 X8 v
- int x = 1;
) H( z$ G6 {. R# D$ t! q: q - void fun() {
- ?8 a" w; ~' H/ w( X L% S. G - cout<<"A namespace"<<endl;
# A( b' M5 }6 A: z - }/ a/ T* s+ `* U; Y6 J; J* t; g
- }. E- W; T3 z+ P8 x
- using namespace A; //声明使用命名空间A
$ G, b3 c! a" q$ H, ]& U1 c/ _ - int main(){
s# o# J" v8 W$ Q: A - fun(); //声明使用命名空间A后,可直接使用fun()
/ a/ y' R) B* l! G% F - A::x = 3; //将A命名空间下的x重新赋值为3
& Q# V4 X5 p' e, A, Z _5 y - cout<<A::x<<endl;# s) w. t0 D$ F$ h
- A::fun();5 W4 D% n5 T! J! \- f9 u) U0 l
- return 0;' i. a; r4 a) D) l) E) E0 C
- }
复制代码执行下面的指令开始编译 - g++ namespace_example.cpp -o namespace_example
复制代码执行./namespace_example后结果如下 - A namespace
X% N7 ]8 U; y" @* K$ ] - 3, o! |; a; Z8 I8 T
- Anamespace
复制代码二. C++面向对象 5 B8 G( c. k! c( O/ [
面向对象的三大特征是继承,多态和封装 2.1 类和对象 类是C++的核心特性,通常被称为用户定义的类型。类用于指定对象的形式,包含了数据表示法和用于处理数据的方法。类中的数据和方法称为类的成员,函数在一个类中被称为类的成员。从类中实例化对象分两种方法,一种是从栈中实例化对象,一种是从堆中实例化对象 0 n$ f7 x. B. E; F
- /***** class_dog_example.cpp *****/
& i: Y2 D4 ?7 F o! {6 f( G8 E+ y - #include <iostream> G- _* q! S* y; C- P# z
- #include <string>2 K6 R. y/ ^( k \# n! @; r0 }
- using namespace std;
1 }) M1 T1 ?( D3 p' l6 D5 a4 ] - ' A M( x4 u# M3 x( R2 g
- class Dog { //定义一个类0 j; S/ V) R; ~, R! I
- public: //访问限定符public(公有的),不写的话默认是private1 L$ _2 u2 D! o* t2 ?! [) E- T
- string name;' D; q! P* d4 |2 s, T" s4 A! b9 s
- int age;
# R( f) n- G2 e -
! d8 }9 t+ {. v% p4 M - void run() { //定义一个方法* [! C+ D: ~' b, A' \9 L1 y Q4 Y
- cout<<"小狗的名字是:"<<name<<","<<"年龄是"<<age<<endl;6 u5 s1 @$ e& H# y ]8 Z# I! C5 J* \
- }
. i" ]4 F3 q; r9 k1 ] J2 c - };1 {; W6 `4 Y0 i
7 D/ u% P9 ^" m( ~4 R9 x+ ~6 S- int main() {: W% T2 e7 a8 S: R
- /* 从栈中实例化一个对象dog1 */
% Q& `# E; a) a( n: Q& \ - Dog dog1;
o$ I; @. L8 x" v$ E \ - dog1.name = "旺财"; //为dog1的成员变量赋值
! ^/ J. E! W; }1 m4 P! ^2 d; z - dog1.age = 2; //为dog1的成员变量赋值/ S" c5 O0 c8 A# G
- dog1.run(); //调用run()方法,打印dog1的相关变量信息5 B: n6 T- H& z! o4 Z
- /* 从堆中实例化对象,使用关键字new的都是从堆中实例化对象 */$ X: @* e. W7 N7 g, @* B A
- Dog *dog2 = new Dog();
, B7 r8 F; S6 b7 F7 K6 `# M4 t - if (NULL == dog2) { //从堆中实例化对象需要开辟内存,指针会指向那个内存
; C% r: d& s! r" _ - return 0;3 O X) N& ~" [/ Y' I; _
- }
- ~) s0 F% N. U - dog2->name = "富贵"; //为dog2的成员变量赋值
D' k, q% {& N4 [0 h - dog2->age = 1; //为dog2的成员变量赋值0 d) R' j+ }1 P% Z( W- q
- dog2->run(); //调用run()方法,打印dog2的相关变量信息
/ V. z9 C8 J+ T; L - 6 G+ D& `# F& D
- delete dog2; //释放内存: o) g. Z% \4 K Y
- dog2 = NULL; //将dog2重新指向NULL0 U" x2 k1 p" x( S% N% e
- return 0;
2 X" S) \7 C2 w( U$ \% } - }
/ I2 P1 L; M- x- N - 执行下面的指令开始编译* [$ Q5 W8 o3 q! I+ f- ~9 P
) b3 _ ]2 f! b9 c: t3 E- g++ class_dog_example.cpp -o class_dog_example7 L% h; |& S$ R J$ G0 d% [) j# B
- 执行./class_dog_example后结果如下
" v" C& M r/ C5 k
; l ^2 O+ \2 C2 Z' k, E4 {' W- 小狗的名字是:旺财,年龄是29 f' g! i Z& t6 e8 Z3 ]
- 小狗的名字是:富贵,年龄是19 F4 ]# b. |6 U
- ⏩ 构造函数与析构函数5 R. b, F; w0 l# s
- 构造函数在对象实例化时被系统自动调用,仅且调用一次。构造函数的特点如下:
9 M# c* H# w( u$ [0 [, ` - 构造函数必须与类名同名4 P( p4 _ y3 ]4 [& c; e0 J# t
- % W$ z0 V7 d* _7 F; u3 R2 {
- 可以重载,没有返回类型$ e: G3 ]; r8 @4 P$ t
6 }0 ]) r- P3 b+ z3 u3 K* H- ^9 o- 构函数在对象结束其生命周期时系统自动执行。析构函数的特点如下:$ J+ J& h7 ^% X& W* ?
- 析构函数的格式为~类名(),调用时释放内存(资源)
7 R( g( F) W! ` - + ~" u9 P7 o% J- \% e; j
- ~类名()不能加参数,没有返回值2 l3 I7 }6 d8 }, y
0 K- n' v9 f8 s" w- 定义类时, 如果没有定义构造函数和析构函数, 编译器就会生成一个构造函数和析构函数, 只是这个构造和析构函数什么事情也不做。当要使用构造函数和析构函数时就需要自己在类里添加
: Y* W3 g4 R& ]/ M. t
' o E) S, ?5 _% a% a/ d* \- /***** structor_example.cpp *****/ c. d6 ~6 `+ y4 E
- #include <iostream>
. z/ k! S4 J( n, R+ n - #include <string>, I/ C# n- t) |2 c1 N6 T
- using namespace std;! _' l/ m1 A3 S" ]3 Z
" y5 w8 h8 f" x' l- class Dog { //定义一个类,并在里面写了构造函数和析构函数
9 ~% B, Q, J+ O1 D - public:. f" n9 u/ U! i7 B0 n+ c! O
- Dog();: c- R0 {2 ]* \! E, S
- ~Dog();
4 \+ N3 T1 ]' U; y - };
$ p n( [4 g7 E R - . L- k5 L( {$ g9 D% d
- int main() {5 {( l- q+ U4 m# L( H+ V# J
- Dog dog; //实例化一个dog对象% \1 c/ Z4 Z. m; R9 F3 u+ y9 c2 |
- cout<<"构造与析构函数示例"<<endl;/ d" a8 }, b! a; q! f
- return 0;& j" i7 n, }* r( k: t
- }
8 P& c( h& S7 N4 Y! t" ~# I. z - //类的函数可在类里实现,也可在类外实现,在类外实现时需要使用“::” J: w/ a1 U. d7 ^+ o1 P/ s! ?
- Dog::Dog() {
4 Y# T" F k7 J( r1 O0 p; ` - cout<<"构造函数执行! "<<endl;6 k8 I7 @2 Y! C7 y3 L7 y2 W+ y
- }
6 T7 c, x7 T# e4 e/ U4 \- K - 2 g+ t! ]' q5 Y# [: c6 Q7 F! K/ ]
- Dog::~Dog() {9 a0 d* Q6 ?: j- ]
- cout<<"析构函数执行! "<<endl;8 c' {: m2 E- o; |- N! W
- }
复制代码执行下面的指令开始编译 - g++ structor_example.cpp -o structor_example
; Y1 k% R% T2 I/ Z* e! Q
复制代码执行./structor_example后结果如下 - 构造函数执行!, Q, Z- ]( @! p& f9 s
- 构造与析构函数示例) O. ^& H& J6 b5 X
- 析构函数执行!
复制代码this指针 每个对象都拥有一个this指针,this指针记录对象的内存地址。this指针是指向类自身数据的指针,简单来说就是指向当前类的当前实例对象。关于类的this指针有以下特点: , ]/ b" W4 ^/ g; T+ _" Q* V
this只能在成员函数中使用,全局函数、静态函数都不能使用this this在成员函数的开始前构造,在成员函数的结束后清除 this指针会因编译器不同而有不同的放置位置。可能是栈,寄存器或者全局变量 $ b: i* K& E6 q
- /***** this_pointer_example.cpp *****/
' _. M* I5 H F f% M; R - #include <iostream>
$ e" E" `1 b5 r1 J- f - #include <string>
" \8 m3 m _) S$ n: j. p* d - using namespace std;
' G" U* m" i& O. L - / P) {" S* }8 v9 X! w3 v. d. B" E( l
- class Dog {
$ N {$ u2 Z+ x$ c- ]! F# e - public:% \) z ]- @ x+ [7 U( S7 V' `3 d3 p
- string name;
1 k2 z+ a7 H. S/ Q) l% r/ ^ - void func();
" }! i1 P3 t; T; l* |, e% N4 W- S' E - };
$ X7 a# c6 B8 O/ y# j0 @5 w- w - $ F7 {! D, R: b/ P
- int main() {
. Z$ p: I+ k- c - Dog dog;8 y/ F" t ^! `7 O7 A+ R
- dog.func();) O W( V5 ?4 P( a' S* D P2 t
- return 0;4 ^2 g% l4 z) G7 ]; c, C
- }
$ ~: ]) o- Q# W - //在类的成员函数里使用了this指针, 并指向了类里的成员name
5 V9 b, ] p" r. F8 q, j - void Dog::func() {; N: H* o5 R* o; p8 x' I' [) u6 f& e
- this->name = "旺财";
2 l8 K8 b' z# e% e/ b0 C% d - cout<<"小狗的名字叫: "<<this->name<<endl;
+ P2 O8 K; d% `" r+ J9 r% N0 q) P5 Y# ~ - }
复制代码执行下面的指令开始编译 - g++ this_pointer_example.cpp -o this_pointer_example
复制代码执行./this_pointer_example后结果如下 - 小狗的名字叫:旺财' L# N2 c# a d# b9 d
复制代码 9 d$ `; q) `! w' N( f
转载自嵌入式攻城狮
; x, p" G6 x2 J$ a
u3 w5 Q( w8 O" I
|