本文是学习谭浩强老师的《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. ;
  10. }

3. 包含类的c++程序

  1. #include <iostream>
  2.  
  3. using namespace std;
  4.  
  5. class Student
  6. {
  7. public:
  8. Student()
  9. {
  10. num = ;
  11. score = ;
  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. ;
  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 = {, , };

6.2 构造函数

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

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

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

(5)构造函数的重载

  1. class Time
  2. {
  3. public:
  4. Time()
  5. {
  6. hour = ;
  7. minute = ;
  8. sec = ;
  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(, , );
  28.  
  29. ;
  30. }

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

  1. class Time
  2. {
  3. public:
  4. Time(, , )
  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(); //一个参数
  21. Time t3(, ); //二个参数
  22. Time t4(, , ); //三个参数
  23.  
  24. ;
  25. }

6.2 析构函数

  1. class Time
  2. {
  3. public:
  4. //构造函数
  5. Time()
  6. {
  7. hour = ;
  8. minute = ;
  9. sec = ;
  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. ;
  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(, ):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[] = {
  27. Student(, ),
  28. Student(),
  29. Student(),
  30. };
  31.  
  32. ; i < ; i++)
  33. {
  34. s[i].display();
  35. }
  36.  
  37. ;
  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(, , ); //定义一个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. ;
  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)实现的。

具体的是:通过继承和虚函数产生不同的派生类,与基类虚函数同名成员在不同派生类中有不同的含义,也就是说多态性是“一个接口,多种方法”。

9.2 虚函数

虚函数的作用是允许在派生类中重新定义与基类同名的函数,并且可以通过基类指针或引用来访问基类和派生类中的同名函数。如果基类的指针是指向基类的对象,则访问基类中的函数,如果基类的指针是指向派生类的对象,则访问派生类中的函数。

9.3 纯虚函数

《c++程序设计》笔记的更多相关文章

  1. HTML+CSS笔记 CSS笔记集合

    HTML+CSS笔记 表格,超链接,图片,表单 涉及内容:表格,超链接,图片,表单 HTML+CSS笔记 CSS入门 涉及内容:简介,优势,语法说明,代码注释,CSS样式位置,不同样式优先级,选择器, ...

  2. CSS笔记--选择器

    CSS笔记--选择器 mate的使用 <meta charset="UTF-8"> <title>Document</title> <me ...

  3. HTML+CSS笔记 CSS中级 一些小技巧

    水平居中 行内元素的水平居中 </a></li> <li><a href="#">2</a></li> &l ...

  4. HTML+CSS笔记 CSS中级 颜色&长度值

    颜色值 在网页中的颜色设置是非常重要,有字体颜色(color).背景颜色(background-color).边框颜色(border)等,设置颜色的方法也有很多种: 1.英文命令颜色 语法: p{co ...

  5. HTML+CSS笔记 CSS中级 缩写入门

    盒子模型代码简写 回忆盒模型时外边距(margin).内边距(padding)和边框(border)设置上下左右四个方向的边距是按照顺时针方向设置的:上右下左. 语法: margin:10px 15p ...

  6. HTML+CSS笔记 CSS进阶再续

    CSS的布局模型 清楚了CSS 盒模型的基本概念. 盒模型类型, 我们就可以深入探讨网页布局的基本模型了.布局模型与盒模型一样都是 CSS 最基本. 最核心的概念. 但布局模型是建立在盒模型基础之上, ...

  7. HTML+CSS笔记 CSS进阶续集

    元素分类 在CSS中,html中的标签元素大体被分为三种不同的类型:块状元素.内联元素(又叫行内元素)和内联块状元素. 常用的块状元素有: <div>.<p>.<h1&g ...

  8. HTML+CSS笔记 CSS进阶

    文字排版 字体 我们可以使用css样式为网页中的文字设置字体.字号.颜色等样式属性. 语法: body{font-family:"宋体";} 这里注意不要设置不常用的字体,因为如果 ...

  9. HTML+CSS笔记 CSS入门续集

    继承 CSS的某些样式是具有继承性的,那么什么是继承呢?继承是一种规则,它允许样式不仅应用于某个特定html标签元素,而且应用于其后代(标签). 语法: p{color:red;} <p> ...

  10. HTML+CSS笔记 CSS入门

    简介: </span>年的圣诞节期间,吉多·范罗苏姆为了在阿姆斯特丹打发时间,决心开发一个新的<span>脚本解释程序</span>,作为ABC语言的一种继承. & ...

随机推荐

  1. 解决方法:loadrunner 场景下执行webservice脚本是---报错10492 Error: Exception was raised when calling per-process-init function in extens

    在vug下执行时,脚本无异常,但是在controller下执行时报下面错误,网上查了下,解决方法千奇百怪,但无一可行. 分析了下错误,似乎是初始化进程有关.想到rts中的设置习惯时以线程方式执行. 遂 ...

  2. PostgreSQL9.6新功能

    PostgreSQL是世界上最先进的开源数据库,9.6最新版本由PostgreSQL全球开发者今天发布. 此版本将允许用户纵向扩展(scale-up)和横向扩展(scale-out)来提高数据库的查询 ...

  3. @Resource注解

    原文地址:http://blog.sina.com.cn/s/blog_a795a96f01016if1.html   @Resource 注解被用来激活一个命名资源(named resource)的 ...

  4. .net framework4与其client profile版本的区别

    简而言之,client profile版本是完整版本的一个子集.包含大多数最常用的功能并减小了体积,以便更容易的安装和发布,同时还有微软所声称的一些好处,比如因为减少了某些库,所以使其更加安全等等. ...

  5. 深入认识JavaScript 中的this指针

    深入认识JavaScript 中的this指针this指针是面向对象程序设计中的一项重要概念,它表示当前运行的对象.在实现对象的方法时,可以使用this指针来获得该对象自身的引用.和传统意义的面向对象 ...

  6. windows系统安装MongoDB

    最近一直在学习node.js,nodejs开发指南中有一个微博的web开发项目,由于该书出的比较早(2012出的),目前为止利用nodejs进行web开发各种组合技术都发生了很大的更新,例如书中选择的 ...

  7. 手机App开发

    /* * 登录:输入 */ public void login(String user, String pwd, TextHttpResponseHandler responsehandler) { ...

  8. RMAN备份与恢复之删除过期备份

    使用crosscheck backupset或crosscheck backup之后,提示所有备份集都为available状态,当他执行delete obsolete时,提示有两个文件需要删除.实际上 ...

  9. 多线程编程之Windows同步方式

    在Windows环境下针对多线程同步与互斥操作的支持,主要包括四种方式:临界区(CriticalSection).互斥对象(Mutex).信号量(Semaphore).事件对象(Event).下面分别 ...

  10. OC中的self指针

    在OC中,self是一个指针,方法和属性可以通过self.function进行访问:成员变量使用self->变量名进行访问.调用方法还可以用[self function]; OC中的self有点 ...