函数重载(Function Overloading)
定义:函数名相同,函数的参数列表包括参数的类型、参数的个数和参数的顺序,只要有一个不同就叫做参数列表不同。
1 2 3 4 5
|
int GetXMLBuffer(const char *in_XMLBuffer,const char *in_FieldName,int *out_Value); int GetXMLBuffer(const char *in_XMLBuffer,const char *in_FieldName,char *out_Value); int GetXMLBuffer(const char *in_XMLBuffer,const char *in_FieldName,double *out_Value);
|
C++编译器在编译的时候会根据参数列表的类型对函数进行重命名,比如:
1
| int GetXMLBuffer_char_char_int(const char *in_XMLBuffer,const char *in_FieldName,int *out_Value);
|
结构体新特征
在C++中,结构体的成员可以有函数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| #include <stdio.h> #include <string.h>
struct st_girl { char name[50]; int age; int height; char sc[30]; char yz[30]; int show(); };
int main() { st_girl stgirl; memset(&stgirl, 0, sizeof(stgirl)); strcpy(stgirl.name, "西施"); stgirl.age = 22; stgirl.height = 168; strcpy(stgirl.sc, "火辣"); strcpy(stgirl.yz, "漂亮");
stgirl.show(); }
int st_girl::show() { printf("name=%s,age=%d,height=%d,sc=%s,yz=%s\n", name, age, height, sc, yz); }
|
类详解
构造函数
- 构造函数必须是 public 属性。
- 构造函数没有返回值,因为没有变量来接收返回值,即使有也毫无用处,不管是声明还是定义,函数名前面都不能出现返回值类型,即使是 void 也不允许。
- 构造函数可以有参数,允许重载。一个类可以有多个重载的构造函数,创建对象时根据传递的参数来判断调用哪一个构造函数。
- 构造函数在实际开发中会大量使用,它往往用来做一些初始化工作,对成员变量进行初始化等,注意,不能用memset对整个类进行初始化。
析构函数
- 析构函数必须是 public 属性的。
- 析构函数没有参数。
- 析构函数没有返回值,因为没有变量来接收返回值,即使有也毫无用处,不管是声明还是定义,函数名前面都不能出现返回值类型,即使是 void 也不允许。
- 析构函数不允许重载的。一个类只能有一个析构函数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
|
class CFile { private: FILE *m_fp; bool m_bEnBuffer; public: CFile(); CFile(bool bEnBuffer); ~CFile(); void EnBuffer(bool bEnBuffer=true); bool Open(const char *filename,const char *openmode); void Fprintf(const char *fmt, ... ); bool Fgets(char *strBuffer,const int ReadSize); void Close(); };
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
CFile::CFile() { m_fp=0; m_bEnBuffer=true; } CFile::CFile(bool bEnBuffer) { m_fp=0; m_bEnBuffer=bEnBuffer; }
CFile::~CFile() { Close(); }
|
C++引用
引用就是变量的别名,对引用的操作与对变量直接操作完全一样。
1 2 3 4 5
| int ii; int &rii=ii; rii=1; 等价于 ii=1;
|
- &在此不是求地址运算,而是声明引用。
- 数据类型可以是C语言的基本数据类型,也可以是结构体和类等构造类型。
- 引用在声明的时候必须对其进行初始化(指向目标变量名),否则编译器会报错。
- 引用初始化之后,不能再用作其他变量名的别名。
- 引用声明后,相当于目标变量名有两个名称。
- 不能建立数组的引用,因为数组是多个变量的集合。
- 引用可以用const修饰,表示只读,用这种方式声明的引用,不能通过引用名对目标变量的值进行修改。
运算符重载
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| #include <stdio.h> #include <string.h> class CGirl // 定义类 { public: char m_name[50]; char m_sc[30]; bool operator==(const CGirl &Girl); }; int main() { CGirl Girl1,Girl2; strcpy(Girl1.m_name,"西施"); strcpy(Girl2.m_name,"东施"); if (Girl1 == Girl2) printf("Girl1和Girl2是同一个人。\n"); else printf("Girl1和Girl2不是同一个人。\n"); } bool CGirl::operator==(const CGirl &Girl) { if (strcmp(m_name,Girl.m_name)== 0) return true; return false; }
|
string类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| #include <string>
using namespace std; string str;
std::string str;
const char *c_str();
int size(); int length(); void clear();
|
vector类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| iterator begin():返回容器头的指针,指向容器第一个元素的位置。
iterator end():返回容器尾的指针,指向容器最后一个元素的下一个位置。
void push_back(const T& x):向容器的尾部增加一个元素x。
iterator insert(iterator it,const T& x):向容器中指定位置(it)前插入一个元素x。
iterator erase(iterator it):删除容器中指定位置(it)的元素。
bool empty():判断容器是否为空。
int size():返回容器中元素的个数。
sort(begin,end,cmp);
|
C++动态内存
1 2 3 4 5 6 7 8 9 10 11 12
| datatype *pointer = new datatype; delete pointer;
int *pi= new int; (*pi)=10; delete pi;
|
继承和派生
1 2 3 4 5 6 7 8 9 10 11 12
| class <派生类名>:<继承方式1><基类名1>,<继承方式2><基类名2>,… { };
class CGirl // 定义超女类 { }
class CKCon:public CGirl {}
|
当一个类派生自基类,该基类可以被继承为 public、protected 或 private 几种方式,当使用不同类型的继承时,遵循以下几个规则:
- 公有继承(public):当类派生以public方式继承时,基类的公有成员也是派生类的公有成员,基类的保护成员也是派生类的保护成员,基类的私有成员不能直接被派生类访问,但是可以通过调用基类的公有和保护成员来访问。
- 保护继承(protected): 当类派生以protected方式继承时,基类的公有和保护成员将成为派生类的保护成员。
- 私有继承(private):当类派生以private方式继承时,基类的公有和保护成员将成为派生类的私有成员。
多态
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| #include <stdio.h> #include <string.h>
class CGirl // 定义超女类 { public: char m_name[50]; int m_age; int m_height; char m_sc[30]; char m_yz[30];
int Show() { printf("CGirl 姓名:%s,年龄:%d,身高:%d,身材:%s,颜值:%s\n", m_name, m_age, m_height, m_sc, m_yz); } };
class CKCon : public CGirl { public: char m_ch[50]; char m_palace[50]; int m_sal;
int Show() { printf("CKCon 姓名:%s,称号:%s,栖:%s,奉禄:%d两银子。\n", m_name, m_ch, m_palace, m_sal); } };
int main() { CKCon KCon;
strcpy(KCon.m_name, "杨玉环"); KCon.m_age = 28; KCon.m_height = 168; strcpy(KCon.m_sc, "火辣"); strcpy(KCon.m_yz, "漂亮"); strcpy(KCon.m_ch, "杨贵妃"); strcpy(KCon.m_palace, "华清宫"); KCon.m_sal = 10000;
CGirl *pGirl; CKCon *pCon;
pGirl = pCon = &KCon;
pGirl->Show(); pCon->Show(); }
|
动态多态
动态多态是在程序运行时根据基类的引用(指针)指向的对象来确定自己具体该调用哪一个类的虚函数。在CGirl类中,Show方法的声明前放置关键字 virtual,则pGirl->Show()会打印出CKCon中的show方法内容。
虚函数
虚函数是在基类中使用关键字 virtual 声明的函数,在派生类中重新定义虚函数。我们想要的是在程序中可以根据所调用的对象类型来选择调用的函数,这种操作被称为动态链接,或后期绑定。
纯虚函数
只声明,具体实现在派生类中实现
1 2 3 4 5 6 7 8 9 10 11
| class CGirl // 定义超女类 { public: char m_name[50]; int m_age; int m_height; char m_sc[30]; char m_yz[30]; virtual int Show()=0; };
|