码迷,mamicode.com
首页 > 编程语言 > 详细

《c++程序设计》笔记

时间:2016-09-15 21:33:12      阅读:242      评论:0      收藏:0      [点我收藏+]

标签:

  本文是学习谭浩强老师的《c++程序设计》后的笔记。

1.概述

c++由c发展而来的,与c兼容。用c语言写的程序可以不加修改用于c++。从c++的名字可以看出它是c的超集。c++即可用于面向过程的程序设计,又可用于面向对象的程序设计,是一种功能强大的混合型程序设计语言。

c++与c语言最大的区别在于:c++增加了面向对象的机制。 

2. 一个简单的c++程序

 1 #include <iostream>
 2 
 3 using namespace std;
 4 
 5 int main()
 6 {
 7     cout << "This is a C++ program." << endl;
 8     
 9     return 0;
10 }

3. 包含类的c++程序

 1 #include <iostream>
 2 
 3 using namespace std;
 4 
 5 class Student
 6 {
 7 public:
 8     Student()
 9     {
10         num = 0;
11         score = 0;
12     }
13 
14     void setData();
15     void display();
16     
17 private:
18     int num;
19     int score;
20 };
21 
22 void Student::setData()
23 {
24     cin >> num >> score;
25 
26     return;
27 }
28 
29 void Student::display()
30 {
31     cout << "num:" << num << " score:" << score << endl;
32  
33     return;
34 }
35 
36 int main()
37 {
38     Student stu;
39     
40     stu.setData();
41     stu.display();
42 
43     return 0;
44 }

  4. c++的特性

面对对象程序设计有4个主要特征:抽象、封装、继承、多态。

(1)抽象

将事物的属性和行为抽象成一种数据类型,这种类型就成为类(class)。类是对象的抽象,而对象时类的实例。

(2)封装

封装有两方面的含义:一是将相关的数据和函数封装在一个对象中,形成一个基本单元,各个对象相互独立,互不干扰;二是将对象中的某些部分对外隐藏,隐藏其中的细节,只留下少量的接口,和外界交互。

这样做的好处是:大大降低操作对象的复杂程度,并且有利于数据的安全,防止无关的人员访问和修改数据。

(3)继承

子类继承父类的成员(属性、方法),目的是减少程序设计,实现“软件重用”的思想。

(4)多态

所谓多态性指:由继承而产生的相关的不用类,其父对象对同一消息做出不同的响应,目的是增加软件的灵活性。

5. 类和对象

5.1 类和对象的关系

类是对象的抽象,是一种类型;对象是类的实例。如同结构体类型和结构体变量的关系一样。

类是抽象的,不占内存空间;对象是具体的,占存储空间。

5.2 声明类类型

1 class 类名
2 {
3 public:
4     公共的成员属性和方法
5 
6 private:
7     私有成员属性和方法 
8 };

5.3 成员访问限定符:

(1)private:私有的成员属性和方法,只能在类中或者类的作用域中使用(友元除外)。

(2)public:公共的成员属性和方法,不仅在类中或者类的作用域中使用,还可以在类外面使用。

(3)protected:受保护的成员属性和方法,和private一样,只能在类中或者类的作用域中使用(友元除外),不同之处的区别在继承中体现。

5.4 定义类对象

(1)先声明类类型,然后在定义对象

 1 class Student
 2 {
 3 public:
 4     ......
 5 
 6 private:
 7     ...... 
 8 };
 9 
10 //带class定义对象
11 class Student stu1, stu2;
12 
13 //不带class定义对象 (推荐这种形式)
14 Student stu1, stu2;

(2)声明类型的同时,定义对象

1 class Student
2 {
3 public:
4     ......
5 
6 private:
7     ......
8 }stu1, stu2;

(3)不出现类名,直接定义对象

1 class
2 {
3 public:
4     ......
5 
6 private:
7     .......
8 }stu1, stu2;

5.5 类和结构体的异同

相同点:class的关键字可以由struct代替。

class和struct的不同点在于:

(1)class默认的成员是private;

(2)struct默认的成员是public。

 1 class Student
 2 {
 3     //私有的
 4     int num;
 5     int score
 6 };
 7 
 8 struct Student
 9 {
10     //公共的
11     int num;
12     int score;
13 };

5.6 成员函数

在类的作用域中叫成员函数,不在类的作用域叫普通函数。

如果在类的外面定义成员函数,需要加上作用域运算符 :: 。

 1 class Student
 2 {
 3 public:
 4     //在类中定义
 5     void setData()
 6     {
 7         cin >> num >> score;
 8 
 9         return;
10     }
11 
12     //在类中声明,在类的作用域定义
13     void display();
14 
15 private:
16     int num;
17     int score;
18 };
19 
20 //在类的作用域定义,需要加上作用域运算符
21 void Student::dispaly()
22 {
23     cout << "num:" << num << " score:" << score << end;
24 
25     return;
26 }

5.7 inline内联函数

inline内联函数和宏函数一样,都是直接在代码中展开,节省了函数带来的开销。

inline比宏函数的优势在于:inline内联函数是成员函数,可以访问类的成员,而宏函数做不到

使用inline内联函数的条件:

(1)代码量少;

(2)调用频繁

 1 class Student
 2 {
 3 public:
 4     //如果在类中定义,默认是inline函数
 5     //inline关键字可以不显示
 6     void setData()
 7     {
 8         cin >> num >> score;
 9 
10         return;
11     }
12 
13     //声明需要显示inline
14     inline void display();
15 
16 private:
17     int num;
18     int score;
19 };
20 
21 inline void Student::display()
22 {
23     cout << "num:" << num << " score:" << score << endl;
24 
25     return;
26 }

5.8 对象的存储方式

对象的数据部分是分开的,函数部分是公共的

技术分享

5.9 对象成员的引用

(1)通过对象名和成员运算符访问

1 Student stu;
2 
3 stu.setData();

(2)通过指向对象的指针访问

1 Student stu;
2 Student *s = &stu;
3 
4 s->setData();

(3)通过对象的引用访问

1 Student stu;
2 Student &s = stu;
3 
4 s.setData();

5.10 如何设计一个优秀的类

(1)公共接口和私有接口要分离;

(2)属性一般设置成private,需要访问和修改数据定义函数接口;

(3)类函数声明和成员函数的实现分离,类声明放在头文件中,实现放在.cpp中。

6. 对类和对象的进一步讨论

6.1 对象的初始化

在创建一个对象时,需要对数据成员初始化。

如果一个类中所有的成员都是public,则可以在定义对象时对数据成员初始化。

如果类中有private和protected的数据成员,不能用这种方式,必须用构造函数初始化。

1 class Time
2 {
3 public:
4     int hour;
5     int minute;
6     int sec;
7 }
8 
9 Time t = {8, 8, 8};

6.2 构造函数

构造函数是初始化对象的数据

(1)不带参数的构造函数,在类中定义

 1 class Time
 2 {
 3 public:
 4     //在类中定义构造函数,内联函数
 5     Time()
 6     {
 7         hour = 0;
 8         minute = 0;
 9         sec = 0;
10     }
11     
12 private:
13     int hour;
14     int minute;
15     int sec;
16 };
17 
18 int main()
19 {
20     Time t;
21     
22     return 0;
23 }

 (2)不带参数的构造函数,在类外定义

 1 class Time
 2 {
 3 public:
 4     Time();
 5     
 6 private:
 7     int hour;
 8     int minute;
 9     int sec;
10 };
11 
12 //在类外定义构造函数
13 Time::Time()
14 {
15     hour = 0;
16     minute = 0;
17     sec = 0;
18 }

(3)带参数的构造函数

 1 class Time
 2 {
 3 public:
 4     Time(int h, int m, int s)
 5     {
 6         hour = h;
 7         minute = m;
 8         sec = s;
 9     }
10     
11 private:
12     int hour;
13     int minute;
14     int sec;
15 };
16 
17 int main()
18 {
19     Time t(8,8,8);
20     
21     return 0;
22 }

(4)用参数初始化表对数据成员初始化

 1 class Time
 2 {
 3 public:
 4     Time(int h, int m, int s)
 5     :hour(h),minute(m),sec(s)
 6     {
 7         
 8     }
 9     
10 private:
11     int hour;
12     int minute;
13     int sec;
14 };
15 
16 int main()
17 {
18     Time t(8, 8, 8);
19     
20     return 0;
21 }

(5)构造函数的重载

 1 class Time
 2 {
 3 public:
 4     Time()
 5     {
 6         hour = 0;
 7         minute = 0;
 8         sec = 0;
 9     }
10     
11     Time(int h, int m, int s)
12     {
13         hour = h;
14         minute = m;
15         sec = s;
16     }
17     
18 private:
19     int hour;
20     int minute;
21     int sec;
22 };
23 
24 int main()
25 {
26     Time t1;
27     Time t2(8, 8, 8);
28     
29     return 0;
30 }

(6)使用默认参数的构造函数,带默认参数的函数不能重载

 1 class Time
 2 {
 3 public:
 4     Time(int h = 8, int m = 8, int s = 8)
 5     {
 6         hour = h;
 7         minute = m;
 8         sec = s;
 9     }
10     
11 private:
12     int hour;
13     int minute;
14     int sec;
15 };
16 
17 int main()
18 {
19     Time t1;            //没有参数
20     Time t2(8);         //一个参数
21     Time t3(8, 8);      //二个参数
22     Time t4(8, 8, 8);   //三个参数
23     
24     return 0;
25 }

6.2 析构函数

 1 class Time
 2 {
 3 public:
 4     //构造函数
 5     Time()
 6     {
 7         hour = 0;
 8         minute = 0;
 9         sec = 0;
10     }
11     
12     //析构函数
13     ~Time()
14     {
15         
16     }
17     
18 private:
19     int hour;
20     int minute;
21     int sec;
22 };
23 
24 int main()
25 {
26     Time t;
27     
28     return 0;
29 }

6.3 调用构造函数和析构函数的顺序

在一般情况下,调用析构函数的顺序与构造函数的次序相反:最先调用的构造函数,与其对应的析构函数最后被调用;最后调用的构造函数,与其对应的析构函数最先被调用。

技术分享

但是,并不是任何情况下都是按这一原则处理的,需要考虑对象的作用域和存储类型。

(1)全局对象:在main函数前,执行构造函数,在程序终止时,调用析构函数。

(2)局部对象:在建立对象时,调用构造函数,在作用域结束后,调用析构函数。

(3)static局部对象:在第一次使用该对象,调用构造函数,在程序终止时,调用析构函数。 

6.4 对象数组

数组不仅可以由简单数据类型组成,还可以由对象组成。

如有3个Student对象,则可以用 Student s[3]表示。

如果构造函数只有一个参数,则可以 Student s[3] = {1, 2, 3},三个参数分别传给三个对象的构造函数。

如果有多个参数,应该这样定义Student s[3] = {Student(1, 100), Student(2, 99), Student(3, 98)};

 1 #include <iostream>
 2 
 3 using namespace std;
 4 
 5 class Student
 6 {
 7 public:
 8     Student(int n = 0, int s = 0):num(n), score(s){};
 9     
10     void display();
11     
12 private:
13     int num;
14     int score;
15 };
16 
17 void Student::display()
18 {
19     cout << "num:" << num << " score:" << score << endl;
20     
21     return;
22 }
23 
24 int main()
25 {
26     Student s[3] = {
27         Student(0, 100),
28         Student(1),
29         Student(),
30     };
31     
32     for (int i = 0; i < 3; i++)
33     {
34         s[i].display();
35     }
36     
37     return 0;
38 }

6.5 对象指针

(1)指向对象的指针

(2)指向对象数据成员的指针

(3)指向对象函数成员的指针

 1 #include <iostream>
 2 
 3 using namespace std;
 4 
 5 class Time
 6 {
 7 public:
 8     Time(int h, int m, int s)
 9     :hour(h),minute(m),sec(s)
10     {
11         
12     }
13 
14     void getTime();
15     
16 public:
17     int hour;
18     int minute;
19     int sec;
20 };
21 
22 void Time::getTime()
23 {
24     cout << "hour:" << hour << " ";
25     cout << "minute:" << minute << " ";
26     cout << "sec:" << sec << endl;
27     
28     return;
29 }
30 
31 int main()
32 {
33     Time t(8, 8, 8);    //定义一个Time类的对象
34     Time *p = &t;        //定义指向t的指针
35     p->getTime();
36    
37     int *p1 = &t.hour;    //定义指向对象数据成员的指针
38     cout << "hour:" << *p1 << endl;
39     
40     void (Time::*p3)(void) = &Time::getTime;    //定义指向对象函数成员的指针
41     (t.*p3)();
42     
43     return 0;
44 }

6.6 this指针

每个对象都有一个this的隐藏指针,当对象调用函数时,会把这个this传进去,这是编译器做的事情。

1 Time(int h, int m, int s)
2 {
3     this->hour = h;
4     this->minute = m;
5     this->sec = s;
6     
7     return;
8 }

6.7 const

(1)常对象

定义常对象的一般格式为:类名 const 对象名;const 类名 对象名。

如果一个对象被声明为常对象,则不能调用该对象的非const成员函数(除了由系统隐式调用的构造函数和析构函数)。

(2)常数据成员

常数据成员的初始化,只能在构造函数中通过参数初始化表进行初始化。

1 const int hour; //定义const成员变量
2 
3 Time(int h):hour(h){}

(3)常成员函数

如果将成员函数声明为常成员函数,则只能引用类中的数据成员,而不能修改它们,例如只用于输出数据等。

const的位置在函数名和()之后。在声明和定义加上const,但是在调用不必加const。

1 void getTime() const;

6.8 对象引用

引用相当于变量的别名。实际上,变量名和引用指向同一段内存单元,引用不占任何空间。

1 Time t;         //定义一个Time类的对象t
2 Time &t1 = t;   //t1是t的引用

6.9 对象的动态建立和释放

在需要这个对象的时候创建,不需要的时候释放,并释放它所占的内存空间,提高内存空间的利用率。

用new运算符动态创建对象,用delete运算符销毁对象。

1 Time *p = new Time;
2 
3 delete p;

6.10 对象的赋值和复制

6.11 static静态成员

(1)静态数据成员

staic静态数据成员被所有对象共用,在内存中占一块空间。

只要在类中定义了static静态数据成员,即使不定义对象,也会分配空间,可以被引用。

static静态数据成员在程序开始时被分配空间,在程序结束时才释放空间。

static静态数据成员可以被初始化,但只能在类外进行初始化,其一般形式:类::静态成员名 = 初值;不必加static,如果未赋初值,则为0。

static静态数据成员既可以用对象名引用,也可以用类名引用。

(2)静态成员函数

6.12 friend友元

友元可以访问其友好关系类中的私有成员。

友元包括:友元函数和友元类。

(1)将普通函数变成友元函数

(2)将成员函数变成友元函数

(3)友元类 

6.13 类模板

如果有两个或者多个类的功能是相同的,仅仅是数据类型不同,则用类模板。

 

7 运算符重载

 

8 继承和派生

 

9 多态性和虚函数

9.1 多态性的概念

在c++程序设计中,多态性是指具有不同功能的函数可以用同一函数名,这样就可以用同一函数名调用不同内容的函数;在面向对象方法中,多态性是指不同的对象接受到同一消息产生不同的行为(方法)。

多态性分2种:静态多态性和动态多态性。函数的重载和运算符重载是静态多态性,在程序编译时决定调用哪个函数,因此静态多态也叫编译时多态;动态多态性是在程序运行过程中才动态确定的,因此动态多态性也叫运行时多态。动态多态性是通过虚函数(virtual)实现的。

《c++程序设计》笔记

标签:

原文地址:http://www.cnblogs.com/gaoningbo/p/5768799.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!