C++三个面向对象开发要素:封装,继承和多态、
集成开发环境IDE
预处理:预处理相当于根据预处理命令组装成新的C程序,不过常以i为扩展名。
编译: 将得到的i文件翻译成汇编代码。s文件。
汇编: 将汇编文件翻译成机器指令,并打包成可重定位目标程序的O文件。该文件是二进制文件,字节编码是机器指令。
链接: 将引用的其他O文件并入到我们程序所在的o文件中,处理得到最终的可执行文件。
使用typedef创建别名 等于同义词,后面跟现有类型和新名称
typedef unsigned short int UNSHORT;
符号常量
1. 使用#define定义常量
#define students 15
2.用const定义常量
const int a = 15
枚举常量:创建新类型,然后定义新类型变量,类型通常为unsigned int
enum color {red, blue, green, white, black}
将color指定为枚举的名称,即它是一个新类型
使red成为一个符号常量,其值为0,blue也是,其值为1
使用关键字const与使用#edfine相比有何优点?
const变量的类型是确定的,编译器能够检查使用它们的方式是否正确。另外经过预处理期处理后,它们仍然存在,因此可以在调试器中是使用它们的名称,最重要是C++标准不再支持使用#define来声明变量
数组要用for循环输入
输入并输出长度不定的一维数组 利用动态内存
cin>>count; //定义数组长度
int *p= new int[count]; //动态分配N个元素的int数组,把数组的指针赋值给p
delete [] p; //删除动态分配的内存
函数重载:在同名的函数的参数列表中,必须有不同的参数类型,参数个数或全部都有。
内联函数:内联函数就是小型函数,牺牲空间来节省函数调用的开销,一般用作比较小的函数,即函数内部没有循环、开关语句等。内联函数被发明出来就是为了取代C中的宏,因为宏是单纯的替换而没有类型检查所以经常出毛病。
打个比方,现在我们要去一个超市买东西,而超市距离我们家有好几里路,此时你要话费一定的时间在去超市的路上,可是现在呢超市已经搬到家里了,我们就没有必要去超市了,因为超市已经在家里了,当然你的家有那么大?能容得下一个超市?所以此时就存在一个空间的问题,即你必须扩大你家,才能够容纳的下一个超市。
对于内存来说也是一样的,减少了对栈的进出时间的开销,我们却扩大了主存的空间来容纳本来在栈里的函数,在C语言中实现这一功能是用内联函数inline来实现的。
函数的递归。
malloc 向系统申请分配指定size个字节的内存空间。//包含#include <malloc.h>
p = (int *) malloc (sizeof(int)*100); 100个int
free(p);
malloc 向系统申请分配指定size个字节的内存空间。返回类型是 void* 类型
delete释放内存块后不要在调用该指针,否则会造成迷途指针情况,导致系统崩溃
指针的赋值:int * a = &i;
指针的赋值:p = &a; 当“=”的左操作数是*p时,改变的是p所指向的地址存放的数据;当“=”的左操作数是p时,改变的是p所指向的地址。
const int* p; 是一个指向整型常量的指针。它指向的值不能修改
int* const p; 是一个指向整型的常量指针。它指向的值可以修改,但不能指向其他变量
const int* const p; 是一个指向整型常量的常量指针。它指向的值不能修改,但不能指向其他变量
理解const关键是看该关键字的位置。如果右边是类型,则值是常量,如果该关键字的右边指针是指针变量,则指针本身是常量。
函数的缺点:参数按值传递;返回语句只能返回一个值。
按引用传递参数有两种方式:使用指针和使用引用
使用指针让swap函数管用 //交换变量的值
swap(&x, &y);
void swap(int *px, int *py)
int temp
temp = *px; *px = *py; *py = *temp;
使用引用来实现:void swap(int &px, int &py)
返回多个值可以用指针或引用实现:void swap(int n, int &px, int &py)
一个通用的设计规则是,让类的数据成员私有化。为了访问类中的私有数据,必须创建被存取器方法的公有函数。这些函数用来设置和获取私有成员变量,它们是成员函数,可以在程序的其他地方调用它们来获取和设置私有成员变量。
构造函数可以根据需要接受参数,但它不能有返回值,连void都不行,构造函数是一个与类同名的类方法。
构造函数和析构函数没有返回值
Cat(int initialAge);
~Cat();
如果声明了一个构造函数,一定要声明一个析构函数,哪怕该析构函数什么也不做。
如果将类方法声明为const,必须保证该函数不会修改任何类成员的值
int GetAge() const;
类的内联函数:内敛函数的函数体紧跟在类方法声明之后,圆括号后面没有分号,像平时函数一样。
int GetAge() const { return itsAge; } // inline
class默认是私有继承,struct默认是公有的。
继承
在已有类的基础上添加了新功能的类被称为从原来的类派生而来,原来的类被称为新类的基类
protected:保护型数据成员和函数对派生类来说完全课件,但对其他类来说是私有的。
隐藏基类方法:覆盖任一个重载方法后,该方法的其他所有版本都将被隐藏,如果不希望他们隐藏,必须对其进行覆盖。
调用积累方法:在方法名前加上基类名和两个冒号:
baseClass::Method()
虚函数
当基类指针指向一个子类对象,通过这个指针调用子类和基类同名成员函数的时候,基类声明为虚函数「子类不写也可以」就会调子类的这个函数,不声明就会调用基类的。
A *p= new B;
p ->show();
虚继承 混合类是多重继承和单继承之间的一种折衷的方案,增加专用功能而不会增加大量方法或数据的类。
只创建一个shape基类,不创建2个重复基类。
class circle: virtual public shape
纯虚函数 virtual double getarea()=0;
引入原因:
1、同“虚函数”;
2、在很多情况下,基类本身生成对象是不合情理的。例如,动物作为一个基类可以派生出老虎、孔雀等子类,但动物本身生成对象明显不合常理。
为什么不将所有函数都声明为虚函数?
虚函数由虚函数表支持,后者会带来运行阶段开销,这种开销表现在程序的大小和性能方面。如果类非常小且预期不会有子类,则不应将其任何函数声明为虚函数。
什么时候应将析构函数声明为虚函数:在您认为类将被用作基类且基类指针将被用来访问派生类对象时。
C++接口是只包含纯虚数的抽象基类。
抽象类:从事实对象抽象出编程对象
#define debug 0
#undef debug 模板是一种对类型进行参数化的工具,通常有两种形式:函数模板和类模板
函数模板:
template <class T>
void swap(T& a, T& b){}
类模板
template<class T>
class A
{public:
T a; T b; T hy(T c, T &d);};
STL容器:顺序容器,关联容器
顺序容器按顺序存储数据,如数组和列表。顺序容器具有插入速度快但查找操作较慢的特征
STL顺序容器:
std::vector 操作与动态数组一样,在最后插入数据
std::deque 与std::vector类似,但也允许在开头插入新元素
std::list 操作跟链表一样
关联容器按指定的顺序存储数据,就像词典一样。单这将降低插入数据的速度,而在查询方面有很大优势
std::set 按排序排列的唯一值列表
std::map 存储键-值对,并根据唯一的键将键-值对排序
std::multiset 与set类似,但允许存储多个值相同的值,即值不需要是唯一的
std::multimap 与map类似,但不要求键是唯一的
集成开发环境IDE
预处理:预处理相当于根据预处理命令组装成新的C程序,不过常以i为扩展名。
编译: 将得到的i文件翻译成汇编代码。s文件。
汇编: 将汇编文件翻译成机器指令,并打包成可重定位目标程序的O文件。该文件是二进制文件,字节编码是机器指令。
链接: 将引用的其他O文件并入到我们程序所在的o文件中,处理得到最终的可执行文件。
使用typedef创建别名 等于同义词,后面跟现有类型和新名称
typedef unsigned short int UNSHORT;
符号常量
1. 使用#define定义常量
#define students 15
2.用const定义常量
const int a = 15
枚举常量:创建新类型,然后定义新类型变量,类型通常为unsigned int
enum color {red, blue, green, white, black}
将color指定为枚举的名称,即它是一个新类型
使red成为一个符号常量,其值为0,blue也是,其值为1
使用关键字const与使用#edfine相比有何优点?
const变量的类型是确定的,编译器能够检查使用它们的方式是否正确。另外经过预处理期处理后,它们仍然存在,因此可以在调试器中是使用它们的名称,最重要是C++标准不再支持使用#define来声明变量
数组要用for循环输入
输入并输出长度不定的一维数组 利用动态内存
cin>>count; //定义数组长度
int *p= new int[count]; //动态分配N个元素的int数组,把数组的指针赋值给p
delete [] p; //删除动态分配的内存
函数重载:在同名的函数的参数列表中,必须有不同的参数类型,参数个数或全部都有。
内联函数:内联函数就是小型函数,牺牲空间来节省函数调用的开销,一般用作比较小的函数,即函数内部没有循环、开关语句等。内联函数被发明出来就是为了取代C中的宏,因为宏是单纯的替换而没有类型检查所以经常出毛病。
打个比方,现在我们要去一个超市买东西,而超市距离我们家有好几里路,此时你要话费一定的时间在去超市的路上,可是现在呢超市已经搬到家里了,我们就没有必要去超市了,因为超市已经在家里了,当然你的家有那么大?能容得下一个超市?所以此时就存在一个空间的问题,即你必须扩大你家,才能够容纳的下一个超市。
对于内存来说也是一样的,减少了对栈的进出时间的开销,我们却扩大了主存的空间来容纳本来在栈里的函数,在C语言中实现这一功能是用内联函数inline来实现的。
函数的递归。
malloc 向系统申请分配指定size个字节的内存空间。//包含#include <malloc.h>
p = (int *) malloc (sizeof(int)*100); 100个int
free(p);
malloc 向系统申请分配指定size个字节的内存空间。返回类型是 void* 类型
delete释放内存块后不要在调用该指针,否则会造成迷途指针情况,导致系统崩溃
指针的赋值:int * a = &i;
指针的赋值:p = &a; 当“=”的左操作数是*p时,改变的是p所指向的地址存放的数据;当“=”的左操作数是p时,改变的是p所指向的地址。
const int* p; 是一个指向整型常量的指针。它指向的值不能修改
int* const p; 是一个指向整型的常量指针。它指向的值可以修改,但不能指向其他变量
const int* const p; 是一个指向整型常量的常量指针。它指向的值不能修改,但不能指向其他变量
理解const关键是看该关键字的位置。如果右边是类型,则值是常量,如果该关键字的右边指针是指针变量,则指针本身是常量。
函数的缺点:参数按值传递;返回语句只能返回一个值。
按引用传递参数有两种方式:使用指针和使用引用
使用指针让swap函数管用 //交换变量的值
swap(&x, &y);
void swap(int *px, int *py)
int temp
temp = *px; *px = *py; *py = *temp;
使用引用来实现:void swap(int &px, int &py)
返回多个值可以用指针或引用实现:void swap(int n, int &px, int &py)
一个通用的设计规则是,让类的数据成员私有化。为了访问类中的私有数据,必须创建被存取器方法的公有函数。这些函数用来设置和获取私有成员变量,它们是成员函数,可以在程序的其他地方调用它们来获取和设置私有成员变量。
构造函数可以根据需要接受参数,但它不能有返回值,连void都不行,构造函数是一个与类同名的类方法。
构造函数和析构函数没有返回值
Cat(int initialAge);
~Cat();
如果声明了一个构造函数,一定要声明一个析构函数,哪怕该析构函数什么也不做。
如果将类方法声明为const,必须保证该函数不会修改任何类成员的值
int GetAge() const;
类的内联函数:内敛函数的函数体紧跟在类方法声明之后,圆括号后面没有分号,像平时函数一样。
int GetAge() const { return itsAge; } // inline
class默认是私有继承,struct默认是公有的。
继承
在已有类的基础上添加了新功能的类被称为从原来的类派生而来,原来的类被称为新类的基类
protected:保护型数据成员和函数对派生类来说完全课件,但对其他类来说是私有的。
隐藏基类方法:覆盖任一个重载方法后,该方法的其他所有版本都将被隐藏,如果不希望他们隐藏,必须对其进行覆盖。
调用积累方法:在方法名前加上基类名和两个冒号:
baseClass::Method()
虚函数
当基类指针指向一个子类对象,通过这个指针调用子类和基类同名成员函数的时候,基类声明为虚函数「子类不写也可以」就会调子类的这个函数,不声明就会调用基类的。
A *p= new B;
p ->show();
虚继承 混合类是多重继承和单继承之间的一种折衷的方案,增加专用功能而不会增加大量方法或数据的类。
只创建一个shape基类,不创建2个重复基类。
class circle: virtual public shape
纯虚函数 virtual double getarea()=0;
引入原因:
1、同“虚函数”;
2、在很多情况下,基类本身生成对象是不合情理的。例如,动物作为一个基类可以派生出老虎、孔雀等子类,但动物本身生成对象明显不合常理。
为什么不将所有函数都声明为虚函数?
虚函数由虚函数表支持,后者会带来运行阶段开销,这种开销表现在程序的大小和性能方面。如果类非常小且预期不会有子类,则不应将其任何函数声明为虚函数。
什么时候应将析构函数声明为虚函数:在您认为类将被用作基类且基类指针将被用来访问派生类对象时。
C++接口是只包含纯虚数的抽象基类。
抽象类:从事实对象抽象出编程对象
#define debug 0
#undef debug 模板是一种对类型进行参数化的工具,通常有两种形式:函数模板和类模板
函数模板:
template <class T>
void swap(T& a, T& b){}
类模板
template<class T>
class A
{public:
T a; T b; T hy(T c, T &d);};
STL容器:顺序容器,关联容器
顺序容器按顺序存储数据,如数组和列表。顺序容器具有插入速度快但查找操作较慢的特征
STL顺序容器:
std::vector 操作与动态数组一样,在最后插入数据
std::deque 与std::vector类似,但也允许在开头插入新元素
std::list 操作跟链表一样
关联容器按指定的顺序存储数据,就像词典一样。单这将降低插入数据的速度,而在查询方面有很大优势
std::set 按排序排列的唯一值列表
std::map 存储键-值对,并根据唯一的键将键-值对排序
std::multiset 与set类似,但允许存储多个值相同的值,即值不需要是唯一的
std::multimap 与map类似,但不要求键是唯一的