《c++程序设计》笔记
本文是学习谭浩强老师的《c++程序设计》后的笔记。
1.概述
c++是贝尔实验室在c语言的基础上发展而来,与c兼容。用c语言写的程序可以不加修改用于c++。从c++的名字可以看出它是c的超集。c++即可用于面向过程的程序设计,又可用于面向对象的程序设计,是一种功能强大的混合型程序设计语言。
c++与c语言最大的区别在于:c++增加了面向对象的机制。
2. 一个简单的c++程序
#include <iostream> using namespace std; int main() { cout << "This is a C++ program." << endl; ; }
3. 包含类的c++程序
#include <iostream> using namespace std; class Student { public: Student() { num = ; score = ; } void setData(); void display(); private: int num; int score; }; void Student::setData() { cin >> num >> score; return; } void Student::display() { cout << "num:" << num << " score:" << score << endl; return; } int main() { Student stu; stu.setData(); stu.display(); ; }
4. c++的特性
面对对象程序设计有4个主要特征:抽象、封装、继承、多态。
(1)抽象
将事物的属性和行为抽象成一种数据类型,这种类型就成为类(class)。类是对象的抽象,而对象时类的实例。
(2)封装
封装有两方面的含义:一是将相关的数据和函数封装在一个对象中,形成一个基本单元,各个对象相互独立,互不干扰;二是将对象中的某些部分对外隐藏,隐藏其中的细节,只留下少量的接口,和外界交互。
这样做的好处是:大大降低操作对象的复杂程度,并且有利于数据的安全,防止无关的人员访问和修改数据。
(3)继承
子类继承父类的成员(属性、方法),目的是减少程序设计,实现“软件重用”的思想。
(4)多态
所谓多态性指:由继承而产生的相关的不用类,其父对象对同一消息做出不同的响应,目的是增加软件的灵活性。
5. 类和对象
5.1 类和对象的关系
类是对象的抽象,是一种类型;对象是类的实例。如同结构体类型和结构体变量的关系一样。
类是抽象的,不占内存空间;对象是具体的,占存储空间。
5.2 声明类类型
class 类名 { public: 公共的成员属性和方法 private: 私有成员属性和方法 };
5.3 成员访问限定符:
(1)private:私有的成员属性和方法,只能在类中或者类的作用域中使用(友元除外)。
(2)public:公共的成员属性和方法,不仅在类中或者类的作用域中使用,还可以在类外面使用。
(3)protected:受保护的成员属性和方法,和private一样,只能在类中或者类的作用域中使用(友元除外),不同之处的区别在继承中体现。
5.4 定义类对象
(1)先声明类类型,然后在定义对象
class Student { public: ...... private: ...... }; //带class定义对象 class Student stu1, stu2; //不带class定义对象 (推荐这种形式) Student stu1, stu2;
(2)声明类型的同时,定义对象
class Student { public: ...... private: ...... }stu1, stu2;
(3)不出现类名,直接定义对象
class { public: ...... private: ....... }stu1, stu2;
5.5 类和结构体的异同
相同点:class的关键字可以由struct代替。
class和struct的不同点在于:
(1)class默认的成员是private;
(2)struct默认的成员是public。
class Student { //私有的 int num; int score }; struct Student { //公共的 int num; int score; };
5.6 成员函数
在类的作用域中叫成员函数,不在类的作用域叫普通函数。
如果在类的外面定义成员函数,需要加上作用域运算符 :: 。
class Student { public: //在类中定义 void setData() { cin >> num >> score; return; } //在类中声明,在类的作用域定义 void display(); private: int num; int score; }; //在类的作用域定义,需要加上作用域运算符 void Student::dispaly() { cout << "num:" << num << " score:" << score << end; return; }
5.7 inline内联函数
inline内联函数和宏函数一样,都是直接在代码中展开,节省了函数带来的开销。
inline比宏函数的优势在于:inline内联函数是成员函数,可以访问类的成员,而宏函数做不到
使用inline内联函数的条件:
(1)代码量少;
(2)调用频繁
class Student { public: //如果在类中定义,默认是inline函数 //inline关键字可以不显示 void setData() { cin >> num >> score; return; } //声明需要显示inline inline void display(); private: int num; int score; }; inline void Student::display() { cout << "num:" << num << " score:" << score << endl; return; }
5.8 对象的存储方式
对象的数据部分是分开的,函数部分是公共的
5.9 对象成员的引用
(1)通过对象名和成员运算符访问
Student stu; stu.setData();
(2)通过指向对象的指针访问
Student stu; Student *s = &stu; s->setData();
(3)通过对象的引用访问
Student stu; Student &s = stu; s.setData();
5.10 如何设计一个优秀的类
(1)公共接口和私有接口要分离;
(2)属性一般设置成private,需要访问和修改数据定义函数接口;
(3)类函数声明和成员函数的实现分离,类声明放在头文件中,实现放在.cpp中。
6. 对类和对象的进一步讨论
6.1 对象的初始化
在创建一个对象时,需要对数据成员初始化。
如果一个类中所有的成员都是public,则可以在定义对象时对数据成员初始化。
如果类中有private和protected的数据成员,不能用这种方式,必须用构造函数初始化。
class Time { public: int hour; int minute; int sec; } Time t = {, , };
6.2 构造函数
构造函数是初始化对象的数据
(1)不带参数的构造函数,在类中定义
class Time { public: //在类中定义构造函数,内联函数 Time() { hour = ; minute = ; sec = ; } private: int hour; int minute; int sec; }; int main() { Time t; ; }
(2)不带参数的构造函数,在类外定义
class Time { public: Time(); private: int hour; int minute; int sec; }; //在类外定义构造函数 Time::Time() { hour = ; minute = ; sec = ; }
(3)带参数的构造函数
class Time { public: Time(int h, int m, int s) { hour = h; minute = m; sec = s; } private: int hour; int minute; int sec; }; int main() { Time t(,,); ; }
(4)用参数初始化表对数据成员初始化
class Time { public: Time(int h, int m, int s) :hour(h),minute(m),sec(s) { } private: int hour; int minute; int sec; }; int main() { Time t(, , ); ; }
(5)构造函数的重载
class Time { public: Time() { hour = ; minute = ; sec = ; } Time(int h, int m, int s) { hour = h; minute = m; sec = s; } private: int hour; int minute; int sec; }; int main() { Time t1; Time t2(, , ); ; }
(6)使用默认参数的构造函数,带默认参数的函数不能重载
class Time { public: Time(, , ) { hour = h; minute = m; sec = s; } private: int hour; int minute; int sec; }; int main() { Time t1; //没有参数 Time t2(); //一个参数 Time t3(, ); //二个参数 Time t4(, , ); //三个参数 ; }
6.2 析构函数
class Time { public: //构造函数 Time() { hour = ; minute = ; sec = ; } //析构函数 ~Time() { } private: int hour; int minute; int sec; }; int main() { Time t; ; }
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)};
#include <iostream> using namespace std; class Student { public: Student(, ):num(n), score(s){}; void display(); private: int num; int score; }; void Student::display() { cout << "num:" << num << " score:" << score << endl; return; } int main() { Student s[] = { Student(, ), Student(), Student(), }; ; i < ; i++) { s[i].display(); } ; }
6.5 对象指针
(1)指向对象的指针
(2)指向对象数据成员的指针
(3)指向对象函数成员的指针
#include <iostream> using namespace std; class Time { public: Time(int h, int m, int s) :hour(h),minute(m),sec(s) { } void getTime(); public: int hour; int minute; int sec; }; void Time::getTime() { cout << "hour:" << hour << " "; cout << "minute:" << minute << " "; cout << "sec:" << sec << endl; return; } int main() { Time t(, , ); //定义一个Time类的对象 Time *p = &t; //定义指向t的指针 p->getTime(); int *p1 = &t.hour; //定义指向对象数据成员的指针 cout << "hour:" << *p1 << endl; void (Time::*p3)(void) = &Time::getTime; //定义指向对象函数成员的指针 (t.*p3)(); ; }
6.6 this指针
每个对象都有一个this的隐藏指针,当对象调用函数时,会把这个this传进去,这是编译器做的事情。
Time(int h, int m, int s) { this->hour = h; this->minute = m; this->sec = s; return; }
6.7 const
(1)常对象
定义常对象的一般格式为:类名 const 对象名;const 类名 对象名。
如果一个对象被声明为常对象,则不能调用该对象的非const成员函数(除了由系统隐式调用的构造函数和析构函数)。
(2)常数据成员
常数据成员的初始化,只能在构造函数中通过参数初始化表进行初始化。
const int hour; //定义const成员变量 Time(int h):hour(h){}
(3)常成员函数
如果将成员函数声明为常成员函数,则只能引用类中的数据成员,而不能修改它们,例如只用于输出数据等。
const的位置在函数名和()之后。在声明和定义加上const,但是在调用不必加const。
void getTime() const;
6.8 对象引用
引用相当于变量的别名。实际上,变量名和引用指向同一段内存单元,引用不占任何空间。
Time t; //定义一个Time类的对象t Time &t1 = t; //t1是t的引用
6.9 对象的动态建立和释放
在需要这个对象的时候创建,不需要的时候释放,并释放它所占的内存空间,提高内存空间的利用率。
用new运算符动态创建对象,用delete运算符销毁对象。
Time *p = new Time; 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++程序设计》笔记的更多相关文章
- HTML+CSS笔记 CSS笔记集合
HTML+CSS笔记 表格,超链接,图片,表单 涉及内容:表格,超链接,图片,表单 HTML+CSS笔记 CSS入门 涉及内容:简介,优势,语法说明,代码注释,CSS样式位置,不同样式优先级,选择器, ...
- CSS笔记--选择器
CSS笔记--选择器 mate的使用 <meta charset="UTF-8"> <title>Document</title> <me ...
- HTML+CSS笔记 CSS中级 一些小技巧
水平居中 行内元素的水平居中 </a></li> <li><a href="#">2</a></li> &l ...
- HTML+CSS笔记 CSS中级 颜色&长度值
颜色值 在网页中的颜色设置是非常重要,有字体颜色(color).背景颜色(background-color).边框颜色(border)等,设置颜色的方法也有很多种: 1.英文命令颜色 语法: p{co ...
- HTML+CSS笔记 CSS中级 缩写入门
盒子模型代码简写 回忆盒模型时外边距(margin).内边距(padding)和边框(border)设置上下左右四个方向的边距是按照顺时针方向设置的:上右下左. 语法: margin:10px 15p ...
- HTML+CSS笔记 CSS进阶再续
CSS的布局模型 清楚了CSS 盒模型的基本概念. 盒模型类型, 我们就可以深入探讨网页布局的基本模型了.布局模型与盒模型一样都是 CSS 最基本. 最核心的概念. 但布局模型是建立在盒模型基础之上, ...
- HTML+CSS笔记 CSS进阶续集
元素分类 在CSS中,html中的标签元素大体被分为三种不同的类型:块状元素.内联元素(又叫行内元素)和内联块状元素. 常用的块状元素有: <div>.<p>.<h1&g ...
- HTML+CSS笔记 CSS进阶
文字排版 字体 我们可以使用css样式为网页中的文字设置字体.字号.颜色等样式属性. 语法: body{font-family:"宋体";} 这里注意不要设置不常用的字体,因为如果 ...
- HTML+CSS笔记 CSS入门续集
继承 CSS的某些样式是具有继承性的,那么什么是继承呢?继承是一种规则,它允许样式不仅应用于某个特定html标签元素,而且应用于其后代(标签). 语法: p{color:red;} <p> ...
- HTML+CSS笔记 CSS入门
简介: </span>年的圣诞节期间,吉多·范罗苏姆为了在阿姆斯特丹打发时间,决心开发一个新的<span>脚本解释程序</span>,作为ABC语言的一种继承. & ...
随机推荐
- 【android极光推送】—从客户端到后台,一文通吃
sion android:name="android.permission.VIBRATE" /> <uses-permission android:name=&quo ...
- java_list,set,map集合
一.集合定义 集合就是讲诺干用途相同.近似的“数据”结合成一个整体 集合从体系上分为三种 1.列表(List):List集合区分元素的顺序,允许包含相同的元素 2.集(set):Set集合不区分元素的 ...
- 木匠ing[索引]
古人有云,一个不会写代码的木匠不会是个好厨子. 为了响应这个号召,开始我的木工之路. 首先介绍一个网站,www.zuojiaju.com 木工爱好者 ,里面有大量的关于木匠的帖子,感谢一下. 以前只是 ...
- css之padding,marging
padding:内边距,所有浏览器都支持,不允许使用负值 继承内部格式生成了10px的边距. 属性: auto:浏览器计算机内边距. length:规定以具体单位计的内边距值,比如像素.厘米等.默认值 ...
- linux apache httpd安装(安装全部modules)
一.安装apache(http服务) 1. 从apache.org下载源码安装包 2. 解压缩# tar zxf httpd-2.2.4.tar.gz# cd httpd-2.2.4 3. 安装apa ...
- [mysql] mysql 5.6.X 慢查询日志
慢查询日志 一篇好文章,学习保存.... 打开慢查询日志 慢查询日志,顾名思义就是记录执行比较慢查询的日志. 查看是否开启慢查询日志: show variables like '%slow%'; 打开 ...
- 【linux】pkill 踢在线用户
[root@Centos ~]# w 01:52:52 up 18 min, 3 users, load average: 0.00, 0.02, 0.05USER TTY FR ...
- ARM汇编常用指令
RAM汇编常用指令有MOV B BL LDR STR
- HttpWebRequest 注意
使用HttpWebRequest 一定要保证GetRequestStream和GetResponse对象关闭,否则容易造成连接处于CLOSE_WAIT状态 using (Stream stream = ...
- QT显示中文的几个问题
最近用QT,需要在界面上显示中文,发现QT无法直接在代码中写中文,只能通过曲线救国的方式,比如用QT语言家,QTextCodec的fromloca8bit 研究了半天,终于明白了一些编码的问题 1.V ...