网站商城注意事项,网页设计师招聘条件,wordpress资讯网站模板,门户网站 建设 通知初始C 注释 变量 常量 关键字 标识符命名规则 数据类型
C规定在创建一个变量或者常量时#xff0c;必须要指定出相应的数据类型#xff0c;否则无法给变量分配内存
整型 sizeof关键字 浮点型#xff08;实型#xff09;
有效位数保留七位#xff0c;带小数点。 这个是保…初始C 注释 变量 常量 关键字 标识符命名规则 数据类型
C规定在创建一个变量或者常量时必须要指定出相应的数据类型否则无法给变量分配内存
整型 sizeof关键字 浮点型实型
有效位数保留七位带小数点。 这个是保留有效数字位数不包括小数点。 字符型 转义字符 字符串型 布尔类型 bool 数据的输入 运算符 算术运算符 赋值运算符 比较运算符 逻辑运算符 程序流程结构 选择结构
if语句 int main() {int score 0;cout 请输入考试分数 endl;cin score;if (score 600){cout 我考上了一本大学 endl;if (score 700){cout 我考上了北大 endl;}else if (score 650){cout 我考上了清华 endl;}else{cout 我考上了人大 endl;}}else if (score 500){cout 我考上了二本大学 endl;}else if (score 400){cout 我考上了三本大学 endl;}else{cout 我未考上本科 endl;}system(pause);return 0;
}
三目运算符 switch语句 循环结构
while循环语句 do...while循环语句 for循环语句 嵌套循环 跳转语句
break语句 continue语句 goto语句 数组 一维数组 冒泡排序 二维数组 函数 函数的定义 函数的调用 值传递 函数的常见样式 函数的声明 函数的分文件编写 指针 指针的定义和使用 每次p的地址是不一样的。 指针所占内存空间 空指针和野指针 const 修饰指针 指针和数组 指针和函数 指针 数组 函数 //冒泡排序函数
void bubbleSort(int * arr, int len) //int * arr 也可以写为int arr[]
{for (int i 0; i len - 1; i){for (int j 0; j len - 1 - i; j){if (arr[j] arr[j 1]){int temp arr[j];arr[j] arr[j 1];arr[j 1] temp;}}}
}//打印数组函数
void printArray(int arr[], int len)
{for (int i 0; i len; i){cout arr[i] endl;}
}int main() {int arr[10] { 4,3,6,9,1,2,10,8,7,5 };int len sizeof(arr) / sizeof(int);bubbleSort(arr, len);printArray(arr, len);system(pause);return 0;
} 结构体 结构体的定义和使用 //结构体定义
struct student
{//成员列表string name; //姓名int age; //年龄int score; //分数
}stu3; //结构体变量创建方式3 int main() {//结构体变量创建方式1struct student stu1; //struct 关键字可以省略stu1.name 张三;stu1.age 18;stu1.score 100;cout 姓名 stu1.name 年龄 stu1.age 分数 stu1.score endl;//结构体变量创建方式2struct student stu2 { 李四,19,60 };cout 姓名 stu2.name 年龄 stu2.age 分数 stu2.score endl;stu3.name 王五;stu3.age 18;stu3.score 80;cout 姓名 stu3.name 年龄 stu3.age 分数 stu3.score endl;system(pause);return 0;
} 结构体数组 结构体指针 结构体嵌套结构体 //学生结构体定义
struct student
{//成员列表string name; //姓名int age; //年龄int score; //分数
};//教师结构体定义
struct teacher
{//成员列表int id; //职工编号string name; //教师姓名int age; //教师年龄struct student stu; //子结构体 学生
};int main() {struct teacher t1;t1.id 10000;t1.name 老王;t1.age 40;t1.stu.name 张三;t1.stu.age 18;t1.stu.score 100;cout 教师 职工编号 t1.id 姓名 t1.name 年龄 t1.age endl;cout 辅导学员 姓名 t1.stu.name 年龄 t1.stu.age 考试分数 t1.stu.score endl;system(pause);return 0;
} 结构体做函数参数 //学生结构体定义
struct student
{//成员列表string name; //姓名int age; //年龄int score; //分数
};//值传递
void printStudent(student stu )
{stu.age 28;cout 子函数中 姓名 stu.name 年龄 stu.age 分数 stu.score endl;
}//地址传递
void printStudent2(student *stu)
{stu-age 28;cout 子函数中 姓名 stu-name 年龄 stu-age 分数 stu-score endl;
}int main() {student stu { 张三,18,100};//值传递printStudent(stu);cout 主函数中 姓名 stu.name 年龄 stu.age 分数 stu.score endl;cout endl;//地址传递printStudent2(stu);cout 主函数中 姓名 stu.name 年龄 stu.age 分数 stu.score endl;system(pause);return 0;
} 结构体中const使用场景 内存分区模型 程序运行前 程序运行后 new操作符 下面实例函数中new 返回的是该数据类型的指针。所以用 int * 来接收。 引用
引用的基本使用 引用的注意事项 引用做函数参数 //1. 值传递
void mySwap01(int a, int b) {int temp a;a b;b temp;
}//2. 地址传递
void mySwap02(int* a, int* b) {int temp *a;*a *b;*b temp;
}//3. 引用传递
void mySwap03(int a, int b) {int temp a;a b;b temp;
}int main() {int a 10;int b 20;mySwap01(a, b);cout a: a b: b endl;mySwap02(a, b);cout a: a b: b endl;mySwap03(a, b);cout a: a b: b endl;system(pause);return 0;
}引用做函数的返回值 //返回局部变量引用
int test01() {int a 10; //局部变量return a;
}//返回静态变量引用
int test02() {static int a 20;return a;
}int main() {//不能返回局部变量的引用int ref test01();cout ref ref endl;cout ref ref endl;//如果函数做左值那么必须返回引用int ref2 test02();cout ref2 ref2 endl;cout ref2 ref2 endl;test02() 1000;cout ref2 ref2 endl;cout ref2 ref2 endl;system(pause);return 0;
}
引用的本质 常量引用 函数提高
函数默认参数 如果我们自己传入了数据就有自己的数据如果没有就用默认值。
函数如果有声明默认值那么函数的实现就不能有声明和实现只能有一个默认参数。例如 1、2
函数占位参数 函数重载 函数重载碰到默认参数会出现二义性报错尽量避免这种情况。
//函数重载需要函数都在同一个作用域下
void func()
{cout func 的调用 endl;
}
void func(int a)
{cout func (int a) 的调用 endl;
}
void func(double a)
{cout func (double a)的调用 endl;
}
void func(int a ,double b)
{cout func (int a ,double b) 的调用 endl;
}
void func(double a ,int b)
{cout func (double a ,int b)的调用 endl;
}//函数返回值不可以作为函数重载条件
//int func(double a, int b)
//{
// cout func (double a ,int b)的调用 endl;
//}int main() {func();func(10);func(3.14);func(10,3.14);func(3.14 , 10);system(pause);return 0;
} 函数重载碰到默认参数会出现二义性报错尽量避免这种情况。
//函数重载注意事项
//1、引用作为重载条件void func(int a)
{cout func (int a) 调用 endl;
}void func(const int a)
{cout func (const int a) 调用 endl;
}//2、函数重载碰到函数默认参数void func2(int a, int b 10)
{cout func2(int a, int b 10) 调用 endl;
}void func2(int a)
{cout func2(int a) 调用 endl;
}int main() {int a 10;func(a); //调用无constfunc(10);//调用有const//func2(10); //碰到默认参数产生歧义需要避免system(pause);return 0;
}
类和对象
封装 //圆周率
const double PI 3.14;//1、封装的意义
//将属性和行为作为一个整体用来表现生活中的事物//封装一个圆类求圆的周长
//class代表设计一个类后面跟着的是类名
class Circle
{
public: //访问权限 公共的权限//属性int m_r;//半径//行为//获取到圆的周长double calculateZC(){//2 * pi * r//获取圆的周长return 2 * PI * m_r;}
};int main() {//通过圆类创建圆的对象// c1就是一个具体的圆Circle c1;c1.m_r 10; //给圆对象的半径 进行赋值操作//2 * pi * 10 62.8cout 圆的周长为 c1.calculateZC() endl;system(pause);return 0;
}
//学生类
class Student {
public:void setName(string name) {m_name name;}void setID(int id) {m_id id;}void showStudent() {cout name: m_name ID: m_id endl;}
public:string m_name;int m_id;
};int main() {Student stu;stu.setName(德玛西亚);stu.setID(250);stu.showStudent();system(pause);return 0;
}#includeiostream
#includeiomanip
#includestring
using namespace std;
class student{
public:int xuehao;string name;void showname(){coutnameendl;}void showxuehao(){coutxuehaoendl;}
};
int main(){student s{11,sjsk};s.namezhangsan;s.showname();s.showxuehao();return 0;
} //三种权限
//公共权限 public 类内可以访问 类外可以访问
//保护权限 protected 类内可以访问 类外不可以访问
//私有权限 private 类内可以访问 类外不可以访问class Person
{//姓名 公共权限
public:string m_Name;//汽车 保护权限
protected:string m_Car;//银行卡密码 私有权限
private:int m_Password;public:void func(){m_Name 张三;m_Car 拖拉机;m_Password 123456;}
};int main() {Person p;p.m_Name 李四;//p.m_Car 奔驰; //保护权限类外访问不到//p.m_Password 123; //私有权限类外访问不到system(pause);return 0;
}
struct和class区别 class C1
{int m_A; //默认是私有权限
};struct C2
{int m_A; //默认是公共权限
};int main() {C1 c1;c1.m_A 10; //错误访问权限是私有C2 c2;c2.m_A 10; //正确访问权限是公共system(pause);return 0;
}
成员属性设置私有 class Person {
public://姓名设置可读可写void setName(string name) {m_Name name;}string getName(){return m_Name;}//获取年龄 int getAge() {return m_Age;}//设置年龄void setAge(int age) {if (age 0 || age 150) {cout 你个老妖精! endl;return;}m_Age age;}//情人设置为只写void setLover(string lover) {m_Lover lover;}private:string m_Name; //可读可写 姓名int m_Age; //只读 年龄string m_Lover; //只写 情人
};int main() {Person p;//姓名设置p.setName(张三);cout 姓名 p.getName() endl;//年龄设置p.setAge(50);cout 年龄 p.getAge() endl;//情人设置p.setLover(苍井);//cout 情人 p.m_Lover endl; //只写属性不可以读取system(pause);return 0;
}
对象的初始化和清理 构造函数和析构函数 class Person
{
public://构造函数Person(){cout Person的构造函数调用 endl;}//析构函数~Person(){cout Person的析构函数调用 endl;}};void test01()
{Person p;
}int main() {test01();system(pause);return 0;
}
构造函数的分类及调用 //1、构造函数分类
// 按照参数分类分为 有参和无参构造 无参又称为默认构造函数
// 按照类型分类分为 普通构造和拷贝构造class Person {
public://无参默认构造函数Person() {cout 无参构造函数! endl;}//有参构造函数Person(int a) {age a;cout 有参构造函数! endl;}//拷贝构造函数Person(const Person p) {age p.age;cout 拷贝构造函数! endl;}//析构函数~Person() {cout 析构函数! endl;}
public:int age;
};//2、构造函数的调用
//调用无参构造函数
void test01() {Person p; //调用无参构造函数
}//调用有参的构造函数
void test02() {//2.1 括号法常用Person p1(10);//注意1调用无参构造函数不能加括号如果加了编译器认为这是一个函数声明//Person p2();//2.2 显式法Person p2 Person(10); Person p3 Person(p2);//Person(10)单独写就是匿名对象 当前行结束之后马上析构//2.3 隐式转换法Person p4 10; // Person p4 Person(10); Person p5 p4; // Person p5 Person(p4); //注意2不能利用 拷贝构造函数 初始化匿名对象 编译器认为是对象声明//Person p5(p4);
}int main() {test01();//test02();system(pause);return 0;
}
拷贝构造函数调用时机 class Person {
public:Person() {cout 无参构造函数! endl;mAge 0;}Person(int age) {cout 有参构造函数! endl;mAge age;}Person(const Person p) {cout 拷贝构造函数! endl;mAge p.mAge;}//析构函数在释放内存之前调用~Person() {cout 析构函数! endl;}
public:int mAge;
};//1. 使用一个已经创建完毕的对象来初始化一个新对象
void test01() {Person man(100); //p对象已经创建完毕Person newman(man); //调用拷贝构造函数Person newman2 man; //拷贝构造//Person newman3;//newman3 man; //不是调用拷贝构造函数赋值操作
}//2. 值传递的方式给函数参数传值
//相当于Person p1 p;
void doWork(Person p1) {}
void test02() {Person p; //无参构造函数doWork(p);
}//3. 以值方式返回局部对象
Person doWork2()
{Person p1;cout (int *)p1 endl;return p1;
}void test03()
{Person p doWork2();cout (int *)p endl;
}int main() {//test01();//test02();test03();system(pause);return 0;
}
构造函数调用规则 class Person {
public://无参默认构造函数Person() {cout 无参构造函数! endl;}//有参构造函数Person(int a) {age a;cout 有参构造函数! endl;}//拷贝构造函数Person(const Person p) {age p.age;cout 拷贝构造函数! endl;}//析构函数~Person() {cout 析构函数! endl;}
public:int age;
};void test01()
{Person p1(18);//如果不写拷贝构造编译器会自动添加拷贝构造并且做浅拷贝操作Person p2(p1);cout p2的年龄为 p2.age endl;
}void test02()
{//如果用户提供有参构造编译器不会提供默认构造会提供拷贝构造Person p1; //此时如果用户自己没有提供默认构造会出错Person p2(10); //用户提供的有参Person p3(p2); //此时如果用户没有提供拷贝构造编译器会提供//如果用户提供拷贝构造编译器不会提供其他构造函数Person p4; //此时如果用户自己没有提供默认构造会出错Person p5(10); //此时如果用户自己没有提供有参会出错Person p6(p5); //用户自己提供拷贝构造
}int main() {test01();system(pause);return 0;
}
深拷贝与浅拷贝 class Person {
public://无参默认构造函数Person() {cout 无参构造函数! endl;}//有参构造函数Person(int age ,int height) {cout 有参构造函数! endl;m_age age;m_height new int(height);}//拷贝构造函数 Person(const Person p) {cout 拷贝构造函数! endl;//如果不利用深拷贝在堆区创建新内存会导致浅拷贝带来的重复释放堆区问题m_age p.m_age;m_height new int(*p.m_height);}//析构函数~Person() {cout 析构函数! endl;if (m_height ! NULL){delete m_height;}}
public:int m_age;int* m_height;
};void test01()
{Person p1(18, 180);Person p2(p1);cout p1的年龄 p1.m_age 身高 *p1.m_height endl;cout p2的年龄 p2.m_age 身高 *p2.m_height endl;
}int main() {test01();system(pause);return 0;
} 初始化列表 class Person {
public:传统方式初始化//Person(int a, int b, int c) {// m_A a;// m_B b;// m_C c;//}//初始化列表方式初始化Person(int a, int b, int c) :m_A(a), m_B(b), m_C(c) {}void PrintPerson() {cout mA: m_A endl;cout mB: m_B endl;cout mC: m_C endl;}
private:int m_A;int m_B;int m_C;
};int main() {Person p(1, 2, 3);p.PrintPerson();system(pause);return 0;
}
类对象作为类成员 class Phone
{
public:Phone(string name){m_PhoneName name;cout Phone构造 endl;}~Phone(){cout Phone析构 endl;}string m_PhoneName;};class Person
{
public://初始化列表可以告诉编译器调用哪一个构造函数Person(string name, string pName) :m_Name(name), m_Phone(pName){cout Person构造 endl;}~Person(){cout Person析构 endl;}void playGame(){cout m_Name 使用 m_Phone.m_PhoneName 牌手机! endl;}string m_Name;Phone m_Phone;};
void test01()
{//当类中成员是其他类对象时我们称该成员为 对象成员//构造的顺序是 先调用对象成员的构造再调用本类构造//析构顺序与构造相反Person p(张三 , 苹果X);p.playGame();}int main() {test01();system(pause);return 0;
}
静态成员 class Person
{public:static int m_A; //静态成员变量//静态成员变量特点//1 在编译阶段分配内存//2 类内声明类外初始化//3 所有对象共享同一份数据private:static int m_B; //静态成员变量也是有访问权限的
};
int Person::m_A 10;
int Person::m_B 10;void test01()
{//静态成员变量两种访问方式//1、通过对象Person p1;p1.m_A 100;cout p1.m_A p1.m_A endl;Person p2;p2.m_A 200;cout p1.m_A p1.m_A endl; //共享同一份数据cout p2.m_A p2.m_A endl;//2、通过类名cout m_A Person::m_A endl;//cout m_B Person::m_B endl; //私有权限访问不到
}int main() {test01();system(pause);return 0;
} class Person
{public://静态成员函数特点//1 程序共享一个函数//2 静态成员函数只能访问静态成员变量static void func(){cout func调用 endl;m_A 100;//m_B 100; //错误不可以访问非静态成员变量}static int m_A; //静态成员变量int m_B; //
private://静态成员函数也是有访问权限的static void func2(){cout func2调用 endl;}
};
int Person::m_A 10;void test01()
{//静态成员变量两种访问方式//1、通过对象Person p1;p1.func();//2、通过类名Person::func();//Person::func2(); //私有权限访问不到
}int main() {test01();system(pause);return 0;
}
C对象模型和this指针
成员变量和成员函数分开存储
C编译器会给每一个空对象也分配一个字节空间是为了区分空对象占内存的位置。
每个空对象都应该有一个独一无二的内存地址。 this指针概念 class Person
{
public:Person(int age){//1、当形参和成员变量同名时可用this指针来区分this-age age;}Person PersonAddPerson(Person p){this-age p.age;//返回对象本身return *this;}int age;
};void test01()
{Person p1(10);cout p1.age p1.age endl;Person p2(10);p2.PersonAddPerson(p1).PersonAddPerson(p1).PersonAddPerson(p1);cout p2.age p2.age endl;
}int main() {test01();system(pause);return 0;
}
空指针访问成员函数 //空指针访问成员函数
class Person {
public:void ShowClassName() {cout 我是Person类! endl;}void ShowPerson() {if (this NULL) {return;}cout mAge endl;}public:int mAge;
};void test01()
{Person * p NULL;p-ShowClassName(); //空指针可以调用成员函数p-ShowPerson(); //但是如果成员函数中用到了this指针就不可以了
}int main() {test01();system(pause);return 0;
}
const修饰成员函数 class Person {
public:Person() {m_A 0;m_B 0;}//this指针的本质是一个指针常量指针的指向不可修改//如果想让指针指向的值也不可以修改需要声明常函数void ShowPerson() const {//const Type* const pointer;//this NULL; //不能修改指针的指向 Person* const this;//this-mA 100; //但是this指针指向的对象的数据是可以修改的//const修饰成员函数表示指针指向的内存空间的数据不能修改除了mutable修饰的变量this-m_B 100;}void MyFunc() const {//mA 10000;}public:int m_A;mutable int m_B; //可修改 可变的
};//const修饰对象 常对象
void test01() {const Person person; //常量对象 cout person.m_A endl;//person.mA 100; //常对象不能修改成员变量的值,但是可以访问person.m_B 100; //但是常对象可以修改mutable修饰成员变量//常对象访问成员函数person.MyFunc(); //常对象不能调用const的函数}int main() {test01();system(pause);return 0;
}
友元 全局函数做友元
class Building
{//告诉编译器 goodGay全局函数 是 Building类的好朋友可以访问类中的私有内容friend void goodGay(Building * building);public:Building(){this-m_SittingRoom 客厅;this-m_BedRoom 卧室;}public:string m_SittingRoom; //客厅private:string m_BedRoom; //卧室
};void goodGay(Building * building)
{cout 好基友正在访问 building-m_SittingRoom endl;cout 好基友正在访问 building-m_BedRoom endl;
}void test01()
{Building b;goodGay(b);
}int main(){test01();system(pause);return 0;
}
类做友元
class Building;
class goodGay
{
public:goodGay();void visit();private:Building *building;
};class Building
{//告诉编译器 goodGay类是Building类的好朋友可以访问到Building类中私有内容friend class goodGay;public:Building();public:string m_SittingRoom; //客厅
private:string m_BedRoom;//卧室
};Building::Building()
{this-m_SittingRoom 客厅;this-m_BedRoom 卧室;
}goodGay::goodGay()
{building new Building;
}void goodGay::visit()
{cout 好基友正在访问 building-m_SittingRoom endl;cout 好基友正在访问 building-m_BedRoom endl;
}void test01()
{goodGay gg;gg.visit();}int main(){test01();system(pause);return 0;
}
成员函数做友元 class Building;
class goodGay
{
public:goodGay();void visit(); //只让visit函数作为Building的好朋友可以发访问Building中私有内容void visit2(); private:Building *building;
};class Building
{//告诉编译器 goodGay类中的visit成员函数 是Building好朋友可以访问私有内容friend void goodGay::visit();public:Building();public:string m_SittingRoom; //客厅
private:string m_BedRoom;//卧室
};Building::Building()
{this-m_SittingRoom 客厅;this-m_BedRoom 卧室;
}goodGay::goodGay()
{building new Building;
}void goodGay::visit()
{cout 好基友正在访问 building-m_SittingRoom endl;cout 好基友正在访问 building-m_BedRoom endl;
}void goodGay::visit2()
{cout 好基友正在访问 building-m_SittingRoom endl;//cout 好基友正在访问 building-m_BedRoom endl;
}void test01()
{goodGay gg;gg.visit();}int main(){test01();system(pause);return 0;
}
运算符重载 加号运算符重载 class Person {
public:Person() {};Person(int a, int b){this-m_A a;this-m_B b;}//成员函数实现 号运算符重载Person operator(const Person p) {Person temp;temp.m_A this-m_A p.m_A;temp.m_B this-m_B p.m_B;return temp;}public:int m_A;int m_B;
};//全局函数实现 号运算符重载
//Person operator(const Person p1, const Person p2) {
// Person temp(0, 0);
// temp.m_A p1.m_A p2.m_A;
// temp.m_B p1.m_B p2.m_B;
// return temp;
//}//运算符重载 可以发生函数重载
Person operator(const Person p2, int val)
{Person temp;temp.m_A p2.m_A val;temp.m_B p2.m_B val;return temp;
}void test() {Person p1(10, 10);Person p2(20, 20);//成员函数方式Person p3 p2 p1; //相当于 p2.operaor(p1)cout mA: p3.m_A mB: p3.m_B endl;Person p4 p3 10; //相当于 operator(p3,10)cout mA: p4.m_A mB: p4.m_B endl;}int main() {test();system(pause);return 0;
} 左移运算符重载 class Person {friend ostream operator(ostream out, Person p);public:Person(int a, int b){this-m_A a;this-m_B b;}//成员函数 实现不了 p cout 不是我们想要的效果//void operator(Person p){//}private:int m_A;int m_B;
};//全局函数实现左移重载
//ostream对象只能有一个
ostream operator(ostream out, Person p) {out a: p.m_A b: p.m_B;return out;
}void test() {Person p1(10, 20);cout p1 hello world endl; //链式编程
}int main() {test();system(pause);return 0;
} 递增运算符重载 class MyInteger {friend ostream operator(ostream out, MyInteger myint);public:MyInteger() {m_Num 0;}//前置MyInteger operator() {//先m_Num;//再返回return *this;}//后置MyInteger operator(int) {//先返回MyInteger temp *this; //记录当前本身的值然后让本身的值加1但是返回的是以前的值达到先返回后m_Num;return temp;}private:int m_Num;
};ostream operator(ostream out, MyInteger myint) {out myint.m_Num;return out;
}//前置 先 再返回
void test01() {MyInteger myInt;cout myInt endl;cout myInt endl;
}//后置 先返回 再
void test02() {MyInteger myInt;cout myInt endl;cout myInt endl;
}int main() {test01();//test02();system(pause);return 0;
} 赋值运算符重载 class Person
{
public:Person(int age){//将年龄数据开辟到堆区m_Age new int(age);}//重载赋值运算符 Person operator(Person p){if (m_Age ! NULL){delete m_Age;m_Age NULL;}//编译器提供的代码是浅拷贝//m_Age p.m_Age;//提供深拷贝 解决浅拷贝的问题m_Age new int(*p.m_Age);//返回自身return *this;}~Person(){if (m_Age ! NULL){delete m_Age;m_Age NULL;}}//年龄的指针int *m_Age;};void test01()
{Person p1(18);Person p2(20);Person p3(30);p3 p2 p1; //赋值操作cout p1的年龄为 *p1.m_Age endl;cout p2的年龄为 *p2.m_Age endl;cout p3的年龄为 *p3.m_Age endl;
}int main() {test01();//int a 10;//int b 20;//int c 30;//c b a;//cout a a endl;//cout b b endl;//cout c c endl;system(pause);return 0;
}
关系运算符重载 class Person
{
public:Person(string name, int age){this-m_Name name;this-m_Age age;};bool operator(Person p){if (this-m_Name p.m_Name this-m_Age p.m_Age){return true;}else{return false;}}bool operator!(Person p){if (this-m_Name p.m_Name this-m_Age p.m_Age){return false;}else{return true;}}string m_Name;int m_Age;
};void test01()
{//int a 0;//int b 0;Person a(孙悟空, 18);Person b(孙悟空, 18);if (a b){cout a和b相等 endl;}else{cout a和b不相等 endl;}if (a ! b){cout a和b不相等 endl;}else{cout a和b相等 endl;}
}int main() {test01();system(pause);return 0;
}
函数调用运算符重载 class MyPrint
{
public:void operator()(string text){cout text endl;}};
void test01()
{//重载的操作符 也称为仿函数MyPrint myFunc;myFunc(hello world);
}class MyAdd
{
public:int operator()(int v1, int v2){return v1 v2;}
};void test02()
{MyAdd add;int ret add(10, 10);cout ret ret endl;//匿名对象调用 cout MyAdd()(100,100) MyAdd()(100, 100) endl;
}int main() {test01();test02();system(pause);return 0;
}
继承 普通实现
//Java页面
class Java
{
public:void header(){cout 首页、公开课、登录、注册...公共头部 endl;}void footer(){cout 帮助中心、交流合作、站内地图...(公共底部) endl;}void left(){cout Java,Python,C...(公共分类列表) endl;}void content(){cout JAVA学科视频 endl;}
};
//Python页面
class Python
{
public:void header(){cout 首页、公开课、登录、注册...公共头部 endl;}void footer(){cout 帮助中心、交流合作、站内地图...(公共底部) endl;}void left(){cout Java,Python,C...(公共分类列表) endl;}void content(){cout Python学科视频 endl;}
};
//C页面
class CPP
{
public:void header(){cout 首页、公开课、登录、注册...公共头部 endl;}void footer(){cout 帮助中心、交流合作、站内地图...(公共底部) endl;}void left(){cout Java,Python,C...(公共分类列表) endl;}void content(){cout C学科视频 endl;}
};void test01()
{//Java页面cout Java下载视频页面如下 endl;Java ja;ja.header();ja.footer();ja.left();ja.content();cout -------------------- endl;//Python页面cout Python下载视频页面如下 endl;Python py;py.header();py.footer();py.left();py.content();cout -------------------- endl;//C页面cout C下载视频页面如下 endl;CPP cp;cp.header();cp.footer();cp.left();cp.content();}int main() {test01();system(pause);return 0;
}
继承实现
//公共页面
class BasePage
{
public:void header(){cout 首页、公开课、登录、注册...公共头部 endl;}void footer(){cout 帮助中心、交流合作、站内地图...(公共底部) endl;}void left(){cout Java,Python,C...(公共分类列表) endl;}};//Java页面
class Java : public BasePage
{
public:void content(){cout JAVA学科视频 endl;}
};
//Python页面
class Python : public BasePage
{
public:void content(){cout Python学科视频 endl;}
};
//C页面
class CPP : public BasePage
{
public:void content(){cout C学科视频 endl;}
};void test01()
{//Java页面cout Java下载视频页面如下 endl;Java ja;ja.header();ja.footer();ja.left();ja.content();cout -------------------- endl;//Python页面cout Python下载视频页面如下 endl;Python py;py.header();py.footer();py.left();py.content();cout -------------------- endl;//C页面cout C下载视频页面如下 endl;CPP cp;cp.header();cp.footer();cp.left();cp.content();}int main() {test01();system(pause);return 0;
} 继承方式 class Base1
{
public: int m_A;
protected:int m_B;
private:int m_C;
};//公共继承
class Son1 :public Base1
{
public:void func(){m_A; //可访问 public权限m_B; //可访问 protected权限//m_C; //不可访问}
};void myClass()
{Son1 s1;s1.m_A; //其他类只能访问到公共权限
}//保护继承
class Base2
{
public:int m_A;
protected:int m_B;
private:int m_C;
};
class Son2:protected Base2
{
public:void func(){m_A; //可访问 protected权限m_B; //可访问 protected权限//m_C; //不可访问}
};
void myClass2()
{Son2 s;//s.m_A; //不可访问
}//私有继承
class Base3
{
public:int m_A;
protected:int m_B;
private:int m_C;
};
class Son3:private Base3
{
public:void func(){m_A; //可访问 private权限m_B; //可访问 private权限//m_C; //不可访问}
};
class GrandSon3 :public Son3
{
public:void func(){//Son3是私有继承所以继承Son3的属性在GrandSon3中都无法访问到//m_A;//m_B;//m_C;}
};
继承中的对象模型 class Base
{
public:int m_A;
protected:int m_B;
private:int m_C; //私有成员只是被隐藏了但是还是会继承下去
};//公共继承
class Son :public Base
{
public:int m_D;
};void test01()
{cout sizeof Son sizeof(Son) endl;
}int main() {test01();system(pause);return 0;
} 继承中的构造和析造顺序 class Base
{
public:Base(){cout Base构造函数! endl;}~Base(){cout Base析构函数! endl;}
};class Son : public Base
{
public:Son(){cout Son构造函数! endl;}~Son(){cout Son析构函数! endl;}};void test01()
{//继承中 先调用父类构造函数再调用子类构造函数析构顺序与构造相反Son s;
}int main() {test01();system(pause);return 0;
} 继承同名成员处理方式 class Base {
public:Base(){m_A 100;}void func(){cout Base - func()调用 endl;}void func(int a){cout Base - func(int a)调用 endl;}public:int m_A;
};class Son : public Base {
public:Son(){m_A 200;}//当子类与父类拥有同名的成员函数子类会隐藏父类中所有版本的同名成员函数//如果想访问父类中被隐藏的同名成员函数需要加父类的作用域void func(){cout Son - func()调用 endl;}
public:int m_A;
};void test01()
{Son s;cout Son下的m_A s.m_A endl;cout Base下的m_A s.Base::m_A endl;s.func();s.Base::func();s.Base::func(10);}
int main() {test01();system(pause);return EXIT_SUCCESS;
} 继承同名静态成员处理方式 class Base {
public:static void func(){cout Base - static void func() endl;}static void func(int a){cout Base - static void func(int a) endl;}static int m_A;
};int Base::m_A 100;class Son : public Base {
public:static void func(){cout Son - static void func() endl;}static int m_A;
};int Son::m_A 200;//同名成员属性
void test01()
{//通过对象访问cout 通过对象访问 endl;Son s;cout Son 下 m_A s.m_A endl;cout Base 下 m_A s.Base::m_A endl;//通过类名访问cout 通过类名访问 endl;cout Son 下 m_A Son::m_A endl;cout Base 下 m_A Son::Base::m_A endl;
}//同名成员函数
void test02()
{//通过对象访问cout 通过对象访问 endl;Son s;s.func();s.Base::func();cout 通过类名访问 endl;Son::func();Son::Base::func();//出现同名子类会隐藏掉父类中所有同名成员函数需要加作作用域访问Son::Base::func(100);
}
int main() {//test01();test02();system(pause);return 0;
} 多继承语法 class Base1 {
public:Base1(){m_A 100;}
public:int m_A;
};class Base2 {
public:Base2(){m_A 200; //开始是m_B 不会出问题但是改为mA就会出现不明确}
public:int m_A;
};//语法class 子类继承方式 父类1 继承方式 父类2
class Son : public Base2, public Base1
{
public:Son(){m_C 300;m_D 400;}
public:int m_C;int m_D;
};//多继承容易产生成员同名的情况
//通过使用类名作用域可以区分调用哪一个基类的成员
void test01()
{Son s;cout sizeof Son sizeof(s) endl;cout s.Base1::m_A endl;cout s.Base2::m_A endl;
}int main() {test01();system(pause);return 0;
} 菱形继承 当菱形继承时两个父类拥有相同数据需要加以作用域区分。
class Animal
{
public:int m_Age;
};//继承前加virtual关键字后变为虚继承
//此时公共的父类Animal称为虚基类
class Sheep : virtual public Animal {};
class Tuo : virtual public Animal {};
class SheepTuo : public Sheep, public Tuo {};void test01()
{SheepTuo st;st.Sheep::m_Age 100;st.Tuo::m_Age 200;cout st.Sheep::m_Age st.Sheep::m_Age endl;cout st.Tuo::m_Age st.Tuo::m_Age endl;cout st.m_Age st.m_Age endl;
}int main() {test01();system(pause);return 0;
} 多态 class Animal
{
public://Speak函数就是虚函数//函数前面加上virtual关键字变成虚函数那么编译器在编译的时候就不能确定函数调用了。virtual void speak(){cout 动物在说话 endl;}
};class Cat :public Animal
{
public:void speak(){cout 小猫在说话 endl;}
};class Dog :public Animal
{
public:void speak(){cout 小狗在说话 endl;}};
//我们希望传入什么对象那么就调用什么对象的函数
//如果函数地址在编译阶段就能确定那么静态联编
//如果函数地址在运行阶段才能确定就是动态联编void DoSpeak(Animal animal)
{animal.speak();
}
//
//多态满足条件
//1、有继承关系
//2、子类重写父类中的虚函数
//多态使用
//父类指针或引用指向子类对象void test01()
{Cat cat;DoSpeak(cat);Dog dog;DoSpeak(dog);
}int main() {test01();system(pause);return 0;
} 纯虚函数和抽象类 class Base
{
public://纯虚函数//类中只要有一个纯虚函数就称为抽象类//抽象类无法实例化对象//子类必须重写父类中的纯虚函数否则也属于抽象类virtual void func() 0;
};class Son :public Base
{
public:virtual void func() {cout func调用 endl;};
};void test01()
{Base * base NULL;//base new Base; // 错误抽象类无法实例化对象base new Son;base-func();delete base;//记得销毁
}int main() {test01();system(pause);return 0;
}
虚析构和纯虚析构 class Animal {
public:Animal(){cout Animal 构造函数调用 endl;}virtual void Speak() 0;//析构函数加上virtual关键字变成虚析构函数//virtual ~Animal()//{// cout Animal虚析构函数调用 endl;//}virtual ~Animal() 0;
};Animal::~Animal()
{cout Animal 纯虚析构函数调用 endl;
}//和包含普通纯虚函数的类一样包含了纯虚析构函数的类也是一个抽象类。不能够被实例化。class Cat : public Animal {
public:Cat(string name){cout Cat构造函数调用 endl;m_Name new string(name);}virtual void Speak(){cout *m_Name 小猫在说话! endl;}~Cat(){cout Cat析构函数调用! endl;if (this-m_Name ! NULL) {delete m_Name;m_Name NULL;}}public:string *m_Name;
};void test01()
{Animal *animal new Cat(Tom);animal-Speak();//通过父类指针去释放会导致子类对象可能清理不干净造成内存泄漏//怎么解决给基类增加一个虚析构函数//虚析构函数就是用来解决通过父类指针释放子类对象delete animal;
}int main() {test01();system(pause);return 0;
} 文件操作 文本文件
写文件 #include fstreamvoid test01()
{ofstream ofs;ofs.open(test.txt, ios::out);ofs 姓名张三 endl;ofs 性别男 endl;ofs 年龄18 endl;ofs.close();
}int main() {test01();system(pause);return 0;
} 读文件 #include fstream
#include string
void test01()
{ifstream ifs;ifs.open(test.txt, ios::in);if (!ifs.is_open()){cout 文件打开失败 endl;return;}//第一种方式//char buf[1024] { 0 };//while (ifs buf)//{// cout buf endl;//}//第二种//char buf[1024] { 0 };//while (ifs.getline(buf,sizeof(buf)))//{// cout buf endl;//}//第三种//string buf;//while (getline(ifs, buf))//{// cout buf endl;//}char c;while ((c ifs.get()) ! EOF){cout c;}ifs.close();}int main() {test01();system(pause);return 0;
} 二进制文件 写文件 #include fstream
#include stringclass Person
{
public:char m_Name[64];int m_Age;
};//二进制文件 写文件
void test01()
{//1、包含头文件//2、创建输出流对象ofstream ofs(person.txt, ios::out | ios::binary);//3、打开文件//ofs.open(person.txt, ios::out | ios::binary);Person p {张三 , 18};//4、写文件ofs.write((const char *)p, sizeof(p));//5、关闭文件ofs.close();
}int main() {test01();system(pause);return 0;
} 读文件 #include fstream
#include stringclass Person
{
public:char m_Name[64];int m_Age;
};void test01()
{ifstream ifs(person.txt, ios::in | ios::binary);if (!ifs.is_open()){cout 文件打开失败 endl;}Person p;ifs.read((char *)p, sizeof(p));cout 姓名 p.m_Name 年龄 p.m_Age endl;
}int main() {test01();system(pause);return 0;
} 模板 函数模板 函数模板 //交换整型函数
void swapInt(int a, int b) {int temp a;a b;b temp;
}//交换浮点型函数
void swapDouble(double a, double b) {double temp a;a b;b temp;
}//利用模板提供通用的交换函数
templatetypename T
void mySwap(T a, T b)
{T temp a;a b;b temp;
}void test01()
{int a 10;int b 20;//swapInt(a, b);//利用模板实现交换//1、自动类型推导mySwap(a, b);//2、显示指定类型mySwapint(a, b);cout a a endl;cout b b endl;}int main() {test01();system(pause);return 0;
} 函数模板注意事项 //利用模板提供通用的交换函数
templateclass T
void mySwap(T a, T b)
{T temp a;a b;b temp;
}// 1、自动类型推导必须推导出一致的数据类型T,才可以使用
void test01()
{int a 10;int b 20;char c c;mySwap(a, b); // 正确可以推导出一致的T//mySwap(a, c); // 错误推导不出一致的T类型
}// 2、模板必须要确定出T的数据类型才可以使用
templateclass T
void func()
{cout func 调用 endl;
}void test02()
{//func(); //错误模板不能独立使用必须确定出T的类型funcint(); //利用显示指定类型的方式给T一个类型才可以使用该模板
}int main() {test01();test02();system(pause);return 0;
} 普通函数与函数模板的区别 //普通函数
int myAdd01(int a, int b)
{return a b;
}//函数模板
templateclass T
T myAdd02(T a, T b)
{return a b;
}//使用函数模板时如果用自动类型推导不会发生自动类型转换,即隐式类型转换
void test01()
{int a 10;int b 20;char c c;cout myAdd01(a, c) endl; //正确将char类型的c隐式转换为int类型 c 对应 ASCII码 99//myAdd02(a, c); // 报错使用自动类型推导时不会发生隐式类型转换myAdd02int(a, c); //正确如果用显示指定类型可以发生隐式类型转换
}int main() {test01();system(pause);return 0;
} 普通函数与函数模板的调用规则 //普通函数与函数模板调用规则
void myPrint(int a, int b)
{cout 调用的普通函数 endl;
}templatetypename T
void myPrint(T a, T b)
{ cout 调用的模板 endl;
}templatetypename T
void myPrint(T a, T b, T c)
{ cout 调用重载的模板 endl;
}void test01()
{//1、如果函数模板和普通函数都可以实现优先调用普通函数// 注意 如果告诉编译器 普通函数是有的但只是声明没有实现或者不在当前文件内实现就会报错找不到int a 10;int b 20;myPrint(a, b); //调用普通函数//2、可以通过空模板参数列表来强制调用函数模板myPrint(a, b); //调用函数模板//3、函数模板也可以发生重载int c 30;myPrint(a, b, c); //调用重载的函数模板//4、 如果函数模板可以产生更好的匹配,优先调用函数模板char c1 a;char c2 b;myPrint(c1, c2); //调用函数模板
}int main() {test01();system(pause);return 0;
} 模板的局限性 #includeiostream
using namespace std;#include stringclass Person
{
public:Person(string name, int age){this-m_Name name;this-m_Age age;}string m_Name;int m_Age;
};//普通函数模板
templateclass T
bool myCompare(T a, T b)
{if (a b){return true;}else{return false;}
}//具体化显示具体化的原型和定意思以template开头并通过名称来指出类型
//具体化优先于常规模板
template bool myCompare(Person p1, Person p2)
{if ( p1.m_Name p2.m_Name p1.m_Age p2.m_Age){return true;}else{return false;}
}void test01()
{int a 10;int b 20;//内置数据类型可以直接使用通用的函数模板bool ret myCompare(a, b);if (ret){cout a b endl;}else{cout a ! b endl;}
}void test02()
{Person p1(Tom, 10);Person p2(Tom, 10);//自定义数据类型不会调用普通的函数模板//可以创建具体化的Person数据类型的模板用于特殊处理这个类型bool ret myCompare(p1, p2);if (ret){cout p1 p2 endl;}else{cout p1 ! p2 endl;}
}int main() {test01();test02();system(pause);return 0;
} 类模板 #include string
//类模板
templateclass NameType, class AgeType
class Person
{
public:Person(NameType name, AgeType age){this-mName name;this-mAge age;}void showPerson(){cout name: this-mName age: this-mAge endl;}
public:NameType mName;AgeType mAge;
};void test01()
{// 指定NameType 为string类型AgeType 为 int类型Personstring, intP1(孙悟空, 999);P1.showPerson();
}int main() {test01();system(pause);return 0;
} 类模板与函数模板的区别 #include string
//类模板
templateclass NameType, class AgeType int
class Person
{
public:Person(NameType name, AgeType age){this-mName name;this-mAge age;}void showPerson(){cout name: this-mName age: this-mAge endl;}
public:NameType mName;AgeType mAge;
};//1、类模板没有自动类型推导的使用方式
void test01()
{// Person p(孙悟空, 1000); // 错误 类模板使用时候不可以用自动类型推导Person string ,intp(孙悟空, 1000); //必须使用显示指定类型的方式使用类模板p.showPerson();
}//2、类模板在模板参数列表中可以有默认参数
void test02()
{Person string p(猪八戒, 999); //类模板中的模板参数列表 可以指定默认参数p.showPerson();
}int main() {test01();test02();system(pause);return 0;
} 类模板中成员函数创建时机 class Person1
{
public:void showPerson1(){cout Person1 show endl;}
};class Person2
{
public:void showPerson2(){cout Person2 show endl;}
};templateclass T
class MyClass
{
public:T obj;//类模板中的成员函数并不是一开始就创建的而是在模板调用时再生成void fun1() { obj.showPerson1(); }void fun2() { obj.showPerson2(); }};void test01()
{MyClassPerson1 m;m.fun1();//m.fun2();//编译会出错说明函数调用才会去创建成员函数
}int main() {test01();system(pause);return 0;
} 类模板对象做函数参数 #include string
//类模板
templateclass NameType, class AgeType int
class Person
{
public:Person(NameType name, AgeType age){this-mName name;this-mAge age;}void showPerson(){cout name: this-mName age: this-mAge endl;}
public:NameType mName;AgeType mAge;
};//1、指定传入的类型
void printPerson1(Personstring, int p)
{p.showPerson();
}
void test01()
{Person string, int p(孙悟空, 100);printPerson1(p);
}//2、参数模板化
template class T1, class T2
void printPerson2(PersonT1, T2p)
{p.showPerson();cout T1的类型为 typeid(T1).name() endl;cout T2的类型为 typeid(T2).name() endl;
}
void test02()
{Person string, int p(猪八戒, 90);printPerson2(p);
}//3、整个类模板化
templateclass T
void printPerson3(T p)
{cout T的类型为 typeid(T).name() endl;p.showPerson();}
void test03()
{Person string, int p(唐僧, 30);printPerson3(p);
}int main() {test01();test02();test03();system(pause);return 0;
} 类模板与继承 templateclass T
class Base
{T m;
};//class Son:public Base //错误c编译需要给子类分配内存必须知道父类中T的类型才可以向下继承
class Son :public Baseint //必须指定一个类型
{
};
void test01()
{Son c;
}//类模板继承类模板 ,可以用T2指定父类中的T类型
templateclass T1, class T2
class Son2 :public BaseT2
{
public:Son2(){cout typeid(T1).name() endl;cout typeid(T2).name() endl;}
};void test02()
{Son2int, char child1;
}int main() {test01();test02();system(pause);return 0;
} 类模板成员函数类外实现
#include string//类模板中成员函数类外实现
templateclass T1, class T2
class Person {
public://成员函数类内声明Person(T1 name, T2 age);void showPerson();public:T1 m_Name;T2 m_Age;
};//构造函数 类外实现
templateclass T1, class T2
PersonT1, T2::Person(T1 name, T2 age) {this-m_Name name;this-m_Age age;
}//成员函数 类外实现
templateclass T1, class T2
void PersonT1, T2::showPerson() {cout 姓名: this-m_Name 年龄: this-m_Age endl;
}void test01()
{Personstring, int p(Tom, 20);p.showPerson();
}int main() {test01();system(pause);return 0;
} 类模板分文件编写 类模板与友元 #include string//2、全局函数配合友元 类外实现 - 先做函数模板声明下方在做函数模板定义在做友元
templateclass T1, class T2 class Person;//如果声明了函数模板可以将实现写到后面否则需要将实现体写到类的前面让编译器提前看到
//templateclass T1, class T2 void printPerson2(PersonT1, T2 p); templateclass T1, class T2
void printPerson2(PersonT1, T2 p)
{cout 类外实现 ---- 姓名 p.m_Name 年龄 p.m_Age endl;
}templateclass T1, class T2
class Person
{//1、全局函数配合友元 类内实现friend void printPerson(PersonT1, T2 p){cout 姓名 p.m_Name 年龄 p.m_Age endl;}//全局函数配合友元 类外实现friend void printPerson2(PersonT1, T2 p);public:Person(T1 name, T2 age){this-m_Name name;this-m_Age age;}private:T1 m_Name;T2 m_Age;};//1、全局函数在类内实现
void test01()
{Person string, int p(Tom, 20);printPerson(p);
}//2、全局函数在类外实现
void test02()
{Person string, int p(Jerry, 30);printPerson2(p);
}int main() {//test01();test02();system(pause);return 0;
} STL