我是靠谱客的博主 无情天空,这篇文章主要介绍c++学习笔记前言Hello world基本语法对象和类,现在分享给大家,希望可以做个参考。

前言

看到本博最近都在学习机器学习,怎么突然冒出一篇C++的笔记,有点突兀……这是因为最近在学怎么获取数据,然后喂给机器学习算法,现在想从原始网络流量包中获取kdd99格式,网上找了下,有个现成的源码是使用C++写的,所以就花了半天时间看了下C++。

也就是说主要目的是为了看懂一个C++原程序,所以和C++相关的知识点是不全的,后续如有时间会再补充更新。

参考书籍《C++Primer.Plus(第6版)》

C++和C语言的主要区别是支持面向对象编程和泛型编程,本笔记不对C语言做记录,而仅记录C++的新特性。

Hello world

先有个直观认识。

运行环境:CentOS 5.4

新建名为hello.cpp的文件,内容如下:

复制代码
1
2
3
4
5
6
7
#include <iostream> int main(int argc, char **argv)#或者int main(void),或者int main() { std::cout << "hello world" << std::endl; return 0; }

编译和运行:

复制代码
1
2
3
4
5
[root@ceshi03 c++]# g++ hello.cpp -o hello [root@ceshi03 c++]# ./hello hello world [root@ceshi03 c++]#

不同编译器约定的语法不一样,常见的有:.cc、.cxx、.cpp、.cp以及.C

基本语法

基本语法主要列出和C语言不一样的内容。

输入输出

需要头文件

复制代码
1
#include <iostream>

标准输入:std::cin

标准输出:std::cout

标准错误:std::cerr和std::clog

例子:

复制代码
1
2
3
4
5
6
7
8
9
#include <iostream> int main() { int a=0, b=0; std::cin >> a >> b; std::cout << "The num of " << a << " and " << b << " is " << a+b << std::endl; return 0; }
复制代码
1
2
3
4
[root@ceshi03 c++]# g++ std.cpp [root@ceshi03 c++]# ./a.out 2 3 The num of 2 and 3 is 5

>>:输入运算符
<<:输出运算符

默认参数

复制代码
1
char * left(const char * str, int n = 1);

函数重载(函数多态)

函数重载和函数多态是同一概念,它支持多个相同的函数名定义,但其形参变量类型或个数不一样,最简单的代码如下所示,其还有一些细节上需要注意的地方,比如哪些可以重载,哪些不可以重载。

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include <iostream> using namespace std; //交换 int 变量的值 void Swap(int *a, int *b){ int temp = *a; *a = *b; *b = temp; } //交换 float 变量的值 void Swap(float *a, float *b){ float temp = *a; *a = *b; *b = temp; } //交换 char 变量的值 void Swap(char *a, char *b){ char temp = *a; *a = *b; *b = temp; } //交换 bool 变量的值 void Swap(bool *a, bool *b){ char temp = *a; *a = *b; *b = temp; } int main(){ //交换 int 变量的值 int n1 = 100, n2 = 200; Swap(&n1, &n2); cout<<n1<<", "<<n2<<endl; //交换 float 变量的值 float f1 = 12.5, f2 = 56.93; Swap(&f1, &f2); cout<<f1<<", "<<f2<<endl; //交换 char 变量的值 char c1 = 'A', c2 = 'B'; Swap(&c1, &c2); cout<<c1<<", "<<c2<<endl; //交换 bool 变量的值 bool b1 = false, b2 = true; Swap(&b1, &b2); cout<<b1<<", "<<b2<<endl; return 0; }

函数模板

在C语言中如果要交换两个int,两个double就要定义两个函数,C++就可以使用函数模板解决这个问题。

定义一个模板:

复制代码
1
template <typename AnyType>

关键字template和typename是必须的,typename位置也可使用class,另外必须使用尖括号,类型名AnyType可以任意选择,只要符合C++命名规范即可,一般常用T来命名。

如下代码演示了模板的使用,它通过调用的地方传入不同类型的变量来决定T的类型,而最终生成带什么类型的函数由编译器完成。

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <iostream> // function template prototype template <typename T> // or class T void Swap(T &a, T &b); int main() { using namespace std; int i = 10; int j = 20; cout << "i, j = " << i << ", " << j << ".n"; cout << "Using compiler-generated int swapper:n"; Swap(i,j); // generates void Swap(int &, int &) cout << "Now i, j = " << i << ", " << j << ".n"; double x = 24.5; double y = 81.7; cout << "x, y = " << x << ", " << y << ".n"; cout << "Using compiler-generated double swapper:n"; Swap(x,y); // generates void Swap(double &, double &) cout << "Now x, y = " << x << ", " << y << ".n"; // cin.get(); return 0; } // function template definition template <typename T> // or class T void Swap(T &a, T &b) { T temp; // temp a variable of type T temp = a; a = b; b = temp; }

模板重载

原来的模板类型为(T &, T&),新模板的类型为(T , T , int)。从中也可以知道模板参数并非一定是模板参数类型,而是可以是具体的类型。

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include <iostream> template <typename T> // original template void Swap(T &a, T &b); template <typename T> // new template void Swap(T *a, T *b, int n); void Show(int a[]); const int Lim = 8; int main() { using namespace std; int i = 10, j = 20; cout << "i, j = " << i << ", " << j << ".n"; cout << "Using compiler-generated int swapper:n"; Swap(i,j); // matches original template cout << "Now i, j = " << i << ", " << j << ".n"; int d1[Lim] = {0,7,0,4,1,7,7,6}; int d2[Lim] = {0,7,2,0,1,9,6,9}; cout << "Original arrays:n"; Show(d1); Show(d2); Swap(d1,d2,Lim); // matches new template cout << "Swapped arrays:n"; Show(d1); Show(d2); // cin.get(); return 0; } template <typename T> void Swap(T &a, T &b) { T temp; temp = a; a = b; b = temp; } template <typename T> void Swap(T a[], T b[], int n) { T temp; for (int i = 0; i < n; i++) { temp = a[i]; a[i] = b[i]; b[i] = temp; } } void Show(int a[]) { using namespace std; cout << a[0] << a[1] << "/"; cout << a[2] << a[3] << "/"; for (int i = 4; i < Lim; i++) cout << a[i]; cout << endl; }

显示具体化(explicit specialization)

如果有多个原型,则编译器在选择原型时,非模板版本优先显示具体化和模板版本,而显示具体化优先模板版本。

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#include <iostream> template <typename T> void Swap(T &a, T &b); struct job { char name[40]; double salary; int floor; }; // explicit specialization template <> void Swap<job>(job &j1, job &j2); void Show(job &j); int main() { using namespace std; cout.precision(2); cout.setf(ios::fixed, ios::floatfield); int i = 10, j = 20; cout << "i, j = " << i << ", " << j << ".n"; cout << "Using compiler-generated int swapper:n"; Swap(i,j); // generates void Swap(int &, int &) cout << "Now i, j = " << i << ", " << j << ".n"; job sue = {"Susan Yaffee", 73000.60, 7}; job sidney = {"Sidney Taffee", 78060.72, 9}; cout << "Before job swapping:n"; Show(sue); Show(sidney); Swap(sue, sidney); // uses void Swap(job &, job &) cout << "After job swapping:n"; Show(sue); Show(sidney); // cin.get(); return 0; } template <typename T> void Swap(T &a, T &b) // general version { T temp; temp = a; a = b; b = temp; } // swaps just the salary and floor fields of a job structure template <> void Swap<job>(job &j1, job &j2) // specialization { double t1; int t2; t1 = j1.salary; j1.salary = j2.salary; j2.salary = t1; t2 = j1.floor; j1.floor = j2.floor; j2.floor = t2; } void Show(job &j) { using namespace std; cout << j.name << ": $" << j.salary << " on floor " << j.floor << endl; }

实例化

之前的例子在调用Swap(i,j)时传入的i,j为int类型,生成一个Swap()的实例,这种实例化称为隐式实例化。C++还允许显示实例化(explicit instantiation),可通过类似的语法:Swap(),其声明所需的种类用<>符号指示类型,并在声明前加上template:

复制代码
1
template void Swap<int>(int, int);

对象和类

面向对象编程(OOP)主要特性:

  • 抽象
  • 封装和数据隐藏
  • 多态
  • 继承
  • 代码的可重用性

C++中的类

定义一个类

文件名:stock00.h

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#ifndef STOCK00_H_ #define STOCK00_H_ #include <string> class Stock // class declaration { private: std::string company; long shares; double share_val; double total_val; void set_tot() { total_val = shares * share_val; } public: void acquire(const std::string & co, long n, double pr); void buy(long num, double price); void sell(long num, double price); void update(double price); void show(); }; // note semicolon at the end #endif

使用类对象的程序可直接访问public部分,但只能通过public函数(或友元函数)来访问对象中的private成员。

实现类成员函数(双冒号::)

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#include <iostream> #include "stock00.h" void Stock::acquire(const std::string & co, long n, double pr) { company = co; if (n < 0) { std::cout << "Number of shares can't be negative; " << company << " shares set to 0.n"; shares = 0; } else shares = n; share_val = pr; set_tot(); } void Stock::buy(long num, double price) { if (num < 0) { std::cout << "Number of shares purchased can't be negative. " << "Transaction is aborted.n"; } else { shares += num; share_val = price; set_tot(); } } void Stock::sell(long num, double price) { using std::cout; if (num < 0) { cout << "Number of shares sold can't be negative. " << "Transaction is aborted.n"; } else if (num > shares) { cout << "You can't sell more than you have! " << "Transaction is aborted.n"; } else { shares -= num; share_val = price; set_tot(); } } void Stock::update(double price) { share_val = price; set_tot(); } void Stock::show() { std::cout << "Company: " << company << " Shares: " << shares << 'n' << " Share Price: $" << share_val << " Total Worth: $" << total_val << 'n'; }

构造函数和析构函数

具体请看例子

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#include <iostream> #include "stock10.h" // constructors (verbose versions) Stock::Stock() //默认构造函数 { std::cout << "Default constructor calledn"; company = "no name"; shares = 0; share_val = 0.0; total_val = 0.0; } Stock::Stock(const std::string & co, long n, double pr) { std::cout << "Constructor using " << co << " calledn"; company = co; if (n < 0) { std::cout << "Number of shares can't be negative; " << company << " shares set to 0.n"; shares = 0; } else shares = n; share_val = pr; set_tot(); } // class destructor Stock::~Stock() //析构函数 { std::cout << "Bye, " << company << "!n"; } // other methods void Stock::buy(long num, double price) { if (num < 0) { std::cout << "Number of shares purchased can't be negative. " << "Transaction is aborted.n"; } else { shares += num; share_val = price; set_tot(); } } void Stock::sell(long num, double price) { using std::cout; if (num < 0) { cout << "Number of shares sold can't be negative. " << "Transaction is aborted.n"; } else if (num > shares) { cout << "You can't sell more than you have! " << "Transaction is aborted.n"; } else { shares -= num; share_val = price; set_tot(); } } void Stock::update(double price) { share_val = price; set_tot(); } void Stock::show() { using std::cout; using std::ios_base; // set format to #.### ios_base::fmtflags orig = cout.setf(ios_base::fixed, ios_base::floatfield); std::streamsize prec = cout.precision(3); cout << "Company: " << company << " Shares: " << shares << 'n'; cout << " Share Price: $" << share_val; // set format to #.## cout.precision(2); cout << " Total Worth: $" << total_val << 'n'; // restore original format cout.setf(orig, ios_base::floatfield); cout.precision(prec); }

构造函数的形参名不能和成员名一样,比如如下代码是错误的:

复制代码
1
Stock::Stock(const stirng &company, long shares, double share_val)

为避免这种混乱,一种方法是在数据成员中使用m_ 前缀,或者使用 _ 后缀,比如

复制代码
1
2
3
4
5
6
7
8
9
class Stock // class declaration { private: std::string m_company; long m_shares; double m_share_val; double m_total_val; ……

或者

复制代码
1
2
3
4
5
6
7
8
9
class Stock // class declaration { private: std::string company_; long shares_; double share_val_; double total_val_; ……

C++ this

this 是 C++ 中的一个关键字,也是一个 const 指针,它指向当前对象,通过它可以访问当前对象的所有成员。

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <iostream> using namespace std; class Student{ public: void setname(char *name); void setage(int age); void setscore(float score); void show(); private: char *name; int age; float score; }; void Student::setname(char *name){ this->name = name; } void Student::setage(int age){ this->age = age; } void Student::setscore(float score){ this->score = score; } void Student::show(){ cout<<this->name<<"的年龄是"<<this->age<<",成绩是"<<this->score<<endl; } int main(){ Student *pstu = new Student; pstu -> setname("李华"); pstu -> setage(16); pstu -> setscore(96.5); pstu -> show(); return 0; }

最后

以上就是无情天空最近收集整理的关于c++学习笔记前言Hello world基本语法对象和类的全部内容,更多相关c++学习笔记前言Hello内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(121)

评论列表共有 0 条评论

立即
投稿
返回
顶部