1.函数重载:writetofile()
C++程序的命名规则
C++输入和输出
C++布尔类型(bool)
C++定义变量的位置
C++函数的缺省参数
C++动态内存分配
在C语言中,动态分配内存用malloc()函数,释放内存用free()函数
C++函数重载
以上为C写法,下面为C++函数重载写法
函数重载规则:1.函数名必须同,2.参数列表必须不同(不能仅仅函数名不同)。
C++是如何做到函数重载的:C++代码在编译时会根据参数列表对函数进行重命名
2.类和对象:vfprintf()
上面完整,下面两行中下行是上行改进,效果一样,但没有涉及类和对象
如下show两个函数同名实现函数重载
结构体升级为类
下面为三种show声明全是类不涉及结构体,struct st_girl——>class CGirl
下面为三种Show调用
下面为三种show函数重载实现,如下字符串也可定义为char name[10],name是字符数组名本身也是一个字符指针,char name不行,char类型是单个字符,所以用char*,想想strcpy函数
对象指针:类是一种自定义的数据类型,对象也是内存变量,也有内存地址,当然也就有了类的指针。
定义指针指向这个地址,将Girl.m_name(类.属性)替换为pst->m_name
对象数组:对象可以被定义成数组对象,本质上与其它类型的数组变量没有区别
对象作为函数的参数:与结构体一样,对象可以作为函数参数传递,最好的办法也是传递对象的地址,*必须&为ox123…
如下这个pst和Girl是一样的,只是名称不同
对象的初始化和占用内存的大小
面向对象编程在代码执行效率上没有任何优势,它的主要目的是方便程序员组织和管理代码,C语言是面向过程,不支持类和对象的概念。C中封装成函数,C++中多了一层封装就是类,所以C++是面向对象
类成员的访问权限
成员变量的命名
构造函数
CFile是类,CFile()是函数,对象没有()。下面return 0;直接返回
如下两个构造函数(该类对象被创建时,编译系统对象分配内存空间,并自动调用该构造函数,由构造函数完成成员的初始化工作),属于成员函数
如上CFile File实例化对象时根据参数选择哪个构造函数
析构函数
构造函数可以重载,一个类可以有多个构造函数
关于类的其它知识如this指针、static静态成员、友元等暂不介绍。下面为CFile类所有成员函数()的实现
如下重写了fprintf(…),调用vfprintf(…)往已打开的文件写入数据
va_list指针,va_start宏,va_end宏,vfprintf(…)把宏分析的结果输出到文件
由上面Fprintf成员函数的实现引出下面可变参数,man sprintf 如下,不是函数重载,省略号代表参数可变
man vfprintf 显示如下,下图中上面函数没有下面函数的功能(va_list分析的结果输出到屏幕,文件…)
3.引用:别名
引用就像起别名,typedef,宏define。对引用的操作与对变量直接操作完全一样
引用的声明方法:类型标识符 &引用名=目标变量名;
引用可以用const修饰,表示只读,用这种方式声明的引用,不能通过引用对目标变量的值进行修改
结构体有引用,但数组没有引用
传地址和引用会搞混
4.string类:string str,str=,str.c_str()
string的重载操作符:=直接赋值,==,>,<,>=,<=,和!=比较字符串,+或者+=操作符连接两个字符串,[ ]获取特定的字符,类似数组
string特性描述函数:int size(); //返回当前字符串大小
int length(); //返回当前字符串的长度
void clear(); //清空字符串
string本质是一个类,通过动态分配内存实现对字符串的存储,string对象用于存放字符的内存地址是变化的。也就是地址存放的下就不再重新分配,存放不下就重新分配地址。
建议采用string存放一些需要动态分配内存的临时数据,避开动态内存技术带来的坑,然后转换为C的字符串。C的字符串没有string类那么丰富的成员函数,这个不是问题,我们可以自己写。与其花时间研究string的成员函数,不如自己写一个
5.vector容器:std::vector<.>.;
容器的定义
vector容器可存放C语言的基本数据类型,可存放结构体和类,链表不讲
容器的使用:1.存放整数
访问容器中元素可以像数组形式一样
2.存放字符串
3.存放结构体
在上面book225.cpp中,采用了memcpy函数(memory),它是C语言的库函数,用于内存中的数据复制,声明如下:
4.存放类:
存放字符串中,string就是类
vector其他成员函数:1.定位的函数
2.增加元素的函数
3.删除元素的函数
4.判断容器的大小
bool empty():判断容器是否为空
int size():返回容器中元素的个数
5.作业题:封装随机数
/*
此程序用于生成一组随机数, 指定数组范围和是否重复
*/
#include"_public.h"
class CRand
{
public:
CRand();
~CRand();
vector <int> m_val; //m_val容器
bool checkexit(const int aryyval, const int aryysize); // 用于检查是否为重复数据,aryyval为重复的值,这函数不单用,用于Rand成员函数里
void Rand(const int minvalue,const int maxvalue,bool brep=true, const int nog=5); //brep为是否允许重复; 默认为允许重复,nog指定生成多少个随机数
};
/////////////////////////////////////////////////////////////////////////////////////////////
void CRand::Rand(const int minvalue,const int maxvalue,bool brep,const int nog)
{
int len = maxvalue-minvalue;
int ii=0, itmp=0, jtmp=0; // ii生成第几个,jtmp生成共多少个,itmp生成的值
m_val.clear();
if(brep==true) // 允许重复
{
jtmp = nog;
for(ii=0;ii<jtmp;ii++)
{
itmp = rand()%(len+1)+minvalue; // (0~len)+minvalue,itmp就是min~max之间的值,不是len长度
m_val.push_back(itmp);
}
return;
}
jtmp = nog; // 不允许重复
if (nog>len) jtmp = len + 1; // 比如5-1=4,但1到5可以生成5个,所以如果nog大于len的话就取len+1个,前提不允许重复。
while(1)
{
if (jtmp == m_val.size()) break; //生成满了跳出循环
itmp = rand()%(len+1)+minvalue;
if (ii==0) // 生成第一个不用管checkexit重不重复
{
m_val.push_back(itmp);
ii++;
continue;
}
if (checkexit(itmp,ii) == false) continue; // checkexit为false则不允许重复
m_val.push_back(itmp); ii++;
}
return;
}
//////////////////////////////////////////////////////////////////
bool CRand::checkexit(const int aryyval, const int aryysize) // aryyval重复的值,aryysize允许多少个重复
{
for (int ii=0; ii<aryysize; ii++)
{
if (aryyval == m_val[ii]) return false;
}
return true;
}
///////////////////////////////////////////////////////
CRand::~CRand()
{
m_val.clear();
}
////////////////////////////////////////////////////
CRand::CRand()
{
struct timeval begin;
gettimeofday(&begin, 0);
srand(begin.tv_usec);
}
///////////////////////////////////////////////////
int main() //如何用CRand这个类
{
CRand CrtRand;
CrtRand.Rand(0, 10, false); // 若false为true允许重复,不管范围多少取nog个
for(int ii=0;ii<CrtRand.m_val.size();ii++)
{
printf("%d\n",CrtRand.m_val[ii]);
}
return 0;
}
6.动态内存:new,delete
动态内存分配场景极少,string和vector已够方便
new关键字进行动态内存申请,C++中的动态内存分配是基于数据类型进行的,delete关键字用于内存释放,语法如下
如果new出来的是类,相当于创建对象,所以会调用构造函数,delete的时候也会调用析构函数