C++ learn 记录一些学c++的笔记吧,主要是跟着b站黑马程序员学的,众所周知,B站是学习网站。目前进度,核心编程学了,提高编程未学。
C++基础入门 就基础方面的话,和c大致差不多,不同点就写下面吧。
输入,输出 c++多了一种输入输出的方式,cin,cout。
1 2 3 4 5 6 7 8 9 10 11 12 #include <iostream> using namespace std ;int main () { int a=10 ; char ch; cin >> ch; cout << ch <<"=" << a << endl ; }
string变量 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 #include <iostream> #include <string> using namespace std ;int main () { char ch[10 ]="hellow" ; string str="world" ; str = "abc" ; cout << str << endl ; }
实战-通讯录管理资料 跟着资料写一写
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 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 #include <iostream> #include <string> using namespace std ;struct person { string name; int sex; int age; string phone; string address; }; int num=0 ;int isexit (struct person *arr, string name) { int i; for (i = 0 ; i < num; i++) { if (arr[i].name == name) { return i; } } return -1 ; } void welcome () { cout << "***************************" << endl ; cout << "***** 1、添加联系人 *****" << endl ; cout << "***** 2、显示联系人 *****" << endl ; cout << "***** 3、删除联系人 *****" << endl ; cout << "***** 4、查找联系人 *****" << endl ; cout << "***** 5、修改联系人 *****" << endl ; cout << "***** 6、清空联系人 *****" << endl ; cout << "***** 0、退出通讯录 *****" << endl ; cout << "***************************" << endl ; } void addcontacts (struct person *arr) { if (num >= 1000 ) { cout << "通讯录已满" << endl ; } else { string name; cout << "请输入姓名:" << endl ; cin >> name; arr[num].name = name; int sex; cout << "请输入性别:" << endl ; cout << "1 -- 男" << endl ; cout << "2 -- 女" << endl ; while (true ) { cin >> sex; if (sex == 1 || sex == 2 ) { arr[num].sex = sex; break ; } cout << "输入有误,请重新输入" ; } cout << "请输入年龄" << endl ; int age; cin >> age; arr[num].age = age; cout << "请输入电话号码" << endl ; string phone; cin >> phone; arr[num].phone = phone; cout << "请输入家庭住址" << endl ; string address; cin >> address; arr[num].address = address; num++; cout << "添加成功" << endl ; system("pause" ); system("cls" ); } } void showcontacts (struct person *arr) { int i; if (num == 0 ) { cout << "当前通讯录里面没有联系人" << endl ; } else { for (i = 0 ; i < num; i++) { cout << "姓名:" << arr[i].name << "\t" ; cout << "性别:" << arr[i].sex << "\t" ; cout << "年龄:" << arr[i].age << "\t" ; cout << "电话号码:" << arr[i].phone << "\t" ; cout << "家庭地址:" << arr[i].address << endl ; } } system("pause" ); system("cls" ); } void deletecontacts (struct person* arr) { string name; int i; int target; cout << "请输入要删除的联系人" << endl ; cin >> name; target = isexit(arr, name); if (target == -1 ) { cout << "没有这个人" << endl ; } else { for (i = target; i < num; i++) { arr[i] = arr[i + 1 ]; } num--; cout << "删除成功" << endl ; } system("pause" ); system("cls" ); } void findcontacts (struct person* arr) { string name; int target = 0 ; cout << "请输入要查找的联系人" << endl ; cin >> name; target = isexit(arr, name); if (target == -1 ) { cout << "没有这个人" << endl ; } else { cout << "姓名:" << arr[target].name << "\t" ; cout << "性别:" << arr[target].sex << "\t" ; cout << "年龄:" << arr[target].age << "\t" ; cout << "电话号码:" << arr[target].phone << "\t" ; cout << "家庭地址:" << arr[target].address << endl ; } system("pause" ); system("cls" ); } void modifycontact (struct person* arr) { string name; int target; cout << "请输入要修改的联系人" << endl ; cin >> name; target = isexit(arr, name); if (target == -1 ) { cout << "没有这个人" << endl ; } else { cout << "请输入姓名:" << endl ; cin >> name; arr[target].name = name; int sex; cout << "请输入性别:" << endl ; cout << "1 -- 男" << endl ; cout << "2 -- 女" << endl ; while (true ) { cin >> sex; if (sex == 1 || sex == 2 ) { arr[target].sex = sex; break ; } cout << "输入有误,请重新输入" ; } cout << "请输入年龄" << endl ; int age; cin >> age; arr[target].age = age; cout << "请输入电话号码" << endl ; string phone; cin >> phone; arr[target].phone = phone; cout << "请输入家庭住址" << endl ; string address; cin >> address; arr[target].address = address; cout << "修改成功" << endl ; } system("pause" ); system("cls" ); } void deleteallcontacts (struct person* arr) { num = 0 ; cout << "所有联系人删除成功" << endl ; system("pause" ); system("cls" ); } int main () { int choice; person arr[10 ]; while (1 ) { welcome(); cin >> choice; switch (choice) { case 1 : addcontacts(arr); break ; case 2 : showcontacts(arr); break ; case 3 : deletecontacts(arr); break ; case 4 : findcontacts(arr); break ; case 5 : modifycontact(arr); break ; case 6 : deleteallcontacts(arr); break ; case 0 : cout << "欢迎下次使用" << endl ; system("pause" ); return 0 ; break ; } } }
C++核心编程 堆空间的申请与释放 c采用不同于malloc,free的方式来向堆区申请与释放空间,而c++还可以用new和delete来向堆区申请与释放空间
#include<iostream>
using namespace std;
int main()
{
int* p = new int(10);
int i;
cout << *p << endl;
delete p;
int* q = new int[10];
for (i = 0; i < 10; i++)
{
q[i] = i;
}
for (i = 0; i < 10; i++)
{
cout << q[i] << endl;
}
delete[] q;
}
引用& 1.c++中的一个知识点,先通过一个例子来认识引用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 #include <iostream> using namespace std ;void main () { int a=0 ; int & b = a; b = 2 ; cout << &b << "\t" << &a << endl ; cout << b << "\t" << a << endl ; }
我们继续通过汇编来看看究竟引用干了什么。
1 2 3 4 5 6 7 8 9 10 int a=0; 001D2602 mov dword ptr [a],0 int& b = a;//可以看到,这个语句就是将a变量的地址给了b 001D2609 lea eax,[a] 001D260C mov dword ptr [b],eax b = 2;//对b进行赋值实际上也是对a在操作 001D260F mov eax,dword ptr [b] 001D2612 mov dword ptr [eax],2
引用&,表面上理解为一种改名操作吧,也是一种特殊的变量类型。
2.然后就是引用的函数应用了,我们都知道,想要用函数来对两个数的值进行真正的交换要用到指针,可是,在c++里面也可以用引用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 #include <iostream> using namespace std ;void swap (int & m, int & n) { int tmp; tmp = m; m = n; n = tmp; } void main () { int a=10 ; int b = 20 ; swap(a, b); cout << a << "\t" << b << endl ; }
可以看到,传入函数的类型居然和函数设置的不一样了,非常不寻常,还是觉得指针用起舒服,实际上感觉这种还是用到的指针,&m,&n,就是a 和b的地址。
3.返回静态变量引用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 #include <iostream> using namespace std ;int & func () { static int a = 10 ; cout << &a << endl ; return a; } int re () { return 10 ; } void main () { int & tmp = func(); cout << &tmp << endl ; cout << &func() << endl ; func() = 20 ; }
里面打印出的地址全是一样的
4.引用的本质,实际上就是个静态指针,或者说是指针常量,也就是指向不能改变的指针。
1 2 3 4 5 6 7 8 9 10 11 12 #include <iostream> using namespace std ;void main () { int a =10 ; int & b = a; int * const p = &a; }
意思就是,我们在写出int& b = a;时,就相当于定义了一个不可修改的指针(int * const p;),然后让p指向了a的地址。
5.常量引用,由于常量不可变,而且在全局区,无法直接引用,必须加const。
1 2 3 4 5 6 7 8 9 #include <iostream> using namespace std ;void main () { int & a = 10 ; const int & b = 10 ; }
函数提高 1.函数默认参数,函数形参可以有默认参数(且从这个默认参数开始都要设置为默认参数),感觉没啥用样,直接在函数内弄一个变量不就可以了吗。
2.函数占位参数
1 2 3 4 5 6 7 8 9 10 11 12 13 #include <iostream> using namespace std ;int func (int a, int ) { return a; } void main () { func(10 , 10 ); }
3.函数重载,就是在满足一定条件下
函数重载满足条件:
同一个作用域下
函数名称相同
函数参数类型不同 或者 个数不同 或者 顺序不同
注意
对于有默认参数的函数,别用函数重载
对于引用时,特别是引用常量,注意有无const。
感觉没必要啊,改个函数名的事情。
类和对象 终于面向对象了。
封装 封装是C++面向对象三大特性之一
封装的意义:
将属性和行为作为一个整体,表现生活中的事物
将属性和行为加以权限控制
直接上两个例子,再来说需要注意的点。
案例1,设计立方体类(Cube),分别用全局函数和成员函数判断两个立方体是否相等。
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 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 #include <iostream> using namespace std ;class Cube {public : void setm_l (int l) { m_l = l; } void setm_h (int h) { m_h = h; } void setm_w (int w) { m_w = w; } int getm_l () { return m_l; } int getm_h () { return m_h; } int getm_w () { return m_w; } bool is_same1 (Cube tmp) { if (tmp.m_h == m_h && tmp.m_l == m_l && tmp.m_w == m_w); { cout << "两个立方体一样" << endl ; } return false ; } private : int m_l, m_h, m_w; }; bool is_same2 (Cube c1,Cube c2) { if (c1.getm_h() == c2.getm_h() && c1.getm_h() == c2.getm_l()&&c1.getm_w()==c2.getm_w()); { cout << "两个立方体一样" << endl ; } return false ; } int main () { Cube c1; c1.setm_h(10 ); c1.setm_l(10 ); c1.setm_w(10 ); Cube c2; c2.setm_h(10 ); c2.setm_l(10 ); c2.setm_w(10 ); c1.is_same1(c2); is_same2(c1, c2); system("pause" ); }
案例2,设计一个圆形类(Circle),和一个点类(Point),计算点和圆的关系。
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 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 #include <iostream> using namespace std ;class Point {public : void setx (int x) { m_x = x; } void sety (int y) { m_y = y; } int getx () { return m_x; } int gety () { return m_y; } private : int m_x, m_y; }; class Circle {public : void setcenter (Point ct) { center = ct; } void setr (int r) { m_r = r; } Point getcenter () { return center; } int getr () { return m_r; } private : Point center; int m_r; }; void check (Point p, Circle c) { int d; int r; d = (c.getcenter().getx() - p.getx()) * (c.getcenter().getx() - p.getx()) + (c.getcenter().gety() - p.gety()) * (c.getcenter().gety() - p.gety()); r = c.getr() * c.getr(); if (d < r) { cout << "在圆内" << endl ; } else if (d == r) { cout << "在圆上" << endl ; } else { cout << "在圆外" << endl ; } } int main () { Point center, point; Circle yuan; center.setx(10 ); center.sety(20 ); point.setx(5 ); point.sety(30 ); yuan.setcenter(center); yuan.setr(15 ); check(point, yuan); system("pause" ); }
现在来说说封装吧,可以看到在class类中,有三种访问权限
三种权限
公共权限 public 类内可以访问 类外可以访问
保护权限 protected 类内可以访问 类外不可以访问
私有权限 private 类内可以访问 类外不可以访问
然后class与我们以前学习的struct很像,但是有一点不同,那就是访问权限,class里面属性的访问权限是默认是private的,而struct是public的。
对于class的private权限,有两个好处
将所有成员属性设置为私有,可以自己控制读写权限,就像两个例子里面的一样。
对于写权限,我们可以检测数据的有效性,比如说写入属性时,必须要满足什么条件,才可以写入。
对象的初始化和清理 1.其实讲的就是构造函数和析构函数,实际上就算我们不写构造和析构,编译器也默认会提供空实现(但是构造函数的拷贝函数不是空实现)。
构造函数:主要作用在于创建对象时为对象的成员属性赋值,构造函数由编译器自动调用,无须手动调用。
析构函数:主要作用在于对象销毁前 系统自动调用,执行一些清理工作。
编译器默认的构造函数和析构函数
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 #include <iostream> using namespace std ;class Person { public : Person() { cout << "Person的构造函数调用" << endl ; } Person(const Person &p) { a = p.a; } ~Person() { cout << "Person的析构函数调用" << endl ; } int a; }; void test01 () { Person p; } int main () { test01(); system("pause" ); return 0 ; }
语法这些后面的例子会存在,我想先写一个老师没讲的析构函数特点。
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 #include <iostream> using namespace std ;class person {public : ~person() { if (h == 10 ) { cout << "p1" << endl ; } else if (h == 11 ) { cout << "p2" << endl ; } } int h; }; void test1 () { person p1; p1.h = 10 ; person p2; p2.h = 11 ; } int main () { test1(); }
这个的打印结果先是p2,后是p1,证明在这个例子中p2这个对象是先销毁的,我猜测可能和栈的结构有关吧,先入后出,后人先出,只是个人猜测。
2.构造函数的分类,老师讲的很详细,就直接腾过来了
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 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 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 p; } void test02 () { Person p1 (10 ) ; Person p2 = Person(10 ); Person p3 = Person(p2); Person p4 = 10 ; Person p5 = p4; } int main () { test01(); system("pause" ); return 0 ; }
3.拷贝构造函数调用时机
使用一个已经创建完毕的对象来初始化一个新对象
值传递的方式给函数参数传值
以值方式返回局部对象
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 #include <iostream> using namespace std ;class Person { public : Person() { cout << "Person的构造函数调用" << endl ; } Person(const Person &p) { age = p.age; } int age; }; void test01 () { Person p; Person p1 (p) ; } void test02 (Person p) {} Person test03 () { Person p; return p; } int main () { test01(); Person person; test02(person); Person q = test03(); }
4.深拷贝与浅拷贝,这个就比较有意思了
浅拷贝,就是编译器默认提供的拷贝,平时普通拷贝到没事,但是如果遇到在堆区申请的空间要拷贝是就会出问题。
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 #include <iostream> using namespace std ;class Person { public : Person(int age,int hight) { m_age = age; m_hight = new int (hight); } ~Person() { if (m_hight != NULL ) { delete m_hight; } } int m_age; int * m_hight; }; void test01 () { Person p (15 ,170 ) ; Person p1 (p) ; } int main () { test01(); }
上面程序会崩,为什么,因为我在定义对象p时,向堆区申请了一块空间,然后将对象p拷贝给对象p1时,编译器默认的拷贝函数也将申请的堆空间地址给了p1的m_hight属性,这两个地址是一样的,这些都没有问题。
问题就出在析构函数,我在析构函数中写了释放堆空间的代码,申请了就要释放,没有问题,而且根据我上面讲的案例,p1这个对象会先被销毁,销毁后申请的堆空间也没了,然后p对象在被销毁时,delete又释放那个空间,就会出问题。
为了解决这种问题,就有了深拷贝。
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 #include <iostream> using namespace std ;class Person { public : Person(int age,int hight) { m_age = age; m_hight = new int (hight); } Person(const Person& tmp) { m_age = tmp.m_age; m_hight = new int (*tmp.m_hight); } ~Person() { if (m_hight != NULL ) { delete m_hight; } } int m_age; int * m_hight; }; void test01 () { Person p (15 ,170 ) ; Person p1 (p) ; } int main () { test01(); }
5.初始化列表
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 #include <iostream> using namespace std ;class Point { public : Point(int x, int y) :m_x(x), m_y(y) { } int m_x; int m_y; }; int main () { Point(1 , 2 ); }
7.类对象作为类成员
这种我们之前在写圆和点关系的案例中实际上就用到过了。
先上例子
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 #include <iostream> using namespace std ;class Point { public : Point() { } Point(int x, int y) { m_x = x; m_y = y; } int m_x; int m_y; }; class Cirle { public : Cirle(int r, int x, int y) :m_r(r), m_point(x, y) { m_r = r; } int m_r; Point m_point; }; int main () { Cirle(1 , 2 , 3 ); }
有一个可以讨论的问题,究竟是m_point这个对象先产生,还是Cirle对象先产生,答案是m_point对象先产生,Cirle对象后产生,而且析构销毁时,Cirle对象先被销毁,m_point对象后被销毁。
8.静态成员
静态成员就是在成员变量和成员函数前加上关键字static,称为静态成员
静态成员分为:
静态成员变量
所有对象共享同一份数据
在编译阶段分配内存
类内声明,类外初始化
静态成员函数
所有对象共享同一个函数
静态成员函数只能访问静态成员变量
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 #include <iostream> using namespace std ;class Point { public : static int m_x; private : static int m_y; }; int Point::m_x = 10 ;int Point::m_y = 10 ;int main () { Point a; Point b; cout << a.m_x << "\t" << b.m_x << endl ; cout << Point::m_x << endl ; a.m_x = 20 ; cout << a.m_x << "\t" << b.m_x << endl ; }
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 50 51 52 53 class Person { public : static void func () { cout << "func调用" << endl ; m_A = 100 ; } static int m_A; int m_B; private : static void func2 () { cout << "func2调用" << endl ; } }; int Person::m_A = 10 ;void test01 () { Person p1; p1.func(); Person::func(); } int main () { test01(); system("pause" ); return 0 ; }
C++对象模型和this指针 1.在C++中,类内的成员变量和成员函数分开存储,只有非静态成员变量才属于类的对象上,而且对于一个空类,其占一个字节。
2.this指针
this指针指向被调用的成员函数所属的对象
this指针的用途:
当形参和成员变量同名时,可用this指针来区分
在类的非静态成员函数中返回对象本身,可使用return *this
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 #include <iostream> using namespace std ;class Person { public : Person(int m_num) { this ->m_num = m_num; } Person add1 (Person p) { this ->m_num += p.m_num; return *this ; } Person& add2 (Person p) { this ->m_num += p.m_num; return *this ; } int m_num; }; void test01 () { Person p1 (10 ) ; p1.add1(p1).add1(p1).add1(p1).m_num; cout << p1.m_num << endl ; } void test02 () { Person p2 (10 ) ; p2.add2(p2).add2(p2).add2(p2).m_num; cout << p2.m_num << endl ; } int main () { test01(); test02(); system("pause" ); }
3.空指针访问成员函数
Person *p=NULL;,这种空指针可以访问类中的成员函数,但是如果用到了this指针,就不可以了,因为这时候相当于this指针是空指针,没有指向任何一个对象。
4.const修饰成员函数,直接复制过来了
常函数:
成员函数后加const后我们称为这个函数为常函数
常函数内不可以修改成员属性
成员属性声明时加关键字mutable后,在常函数中依然可以修改
常对象:
声明对象前加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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 class Person {public : Person() { m_A = 0 ; m_B = 0 ; } void ShowPerson () const { this ->m_B = 100 ; } void MyFunc () const { } public : int m_A; mutable int m_B; }; void test01 () { const Person person; cout << person.m_A << endl ; person.m_B = 100 ; person.MyFunc(); } int main () { test01(); system("pause" ); return 0 ; }
友元 1.全局函数做友元
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 #include <iostream> #include <string> using namespace std ;class house { friend void gay (house* tmp) ; public : house() { m_SittingRoom = "客厅" ; m_BedRoom = "卧室" ; } string m_SittingRoom; private : string m_BedRoom; }; void gay (house* tmp) { cout << tmp->m_SittingRoom << endl ; cout << tmp->m_BedRoom << endl ; } int main () { house h; gay(&h); system("pause" ); }
2.类做友元
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 50 51 52 53 54 55 56 #include <iostream> #include <string> using namespace std ;class Building { friend class goodGay ; public : Building() { this ->m_SittingRoom = "客厅" ; this ->m_BedRoom = "卧室" ; } public : string m_SittingRoom; private : string m_BedRoom; }; class goodGay { public : goodGay() { building = new Building; } void visit () { cout << "好基友正在访问" << building->m_SittingRoom << endl ; cout << "好基友正在访问" << building->m_BedRoom << endl ; } private : Building* building; }; void test01 () { goodGay gg; gg.visit(); } int main () { test01(); system("pause" ); return 0 ; }
3.成员函数做友元
这个里面有个点没搞懂,可以看下面代码中的成员函数是在类外写的,如果改为在类中写,程序会报错。
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 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 #include <iostream> #include <string> using namespace std ;class Building ;class goodGay { public : goodGay(); void visit () ; void visit2 () ; private : Building* building; }; class 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 ; } void test01 () { goodGay gg; gg.visit(); } int main () { test01(); system("pause" ); return 0 ; }
运算符重载 1.加号运算符重载,可以用成员函数实现,也可以用全局函数实现。
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 #include <iostream> using namespace std ;class Person {public : Person(int a) { m_num = a; } Person operator +(Person &p) { Person temp (0 ) ; temp.m_num = this ->m_num + p.m_num; return temp; } int m_num; }; void test01 () { Person p1 (1 ) ; Person p2 (1 ) ; Person p3 = p1 + p2; cout << p3.m_num << endl ; } void test02 () {} int main () { test01(); system("pause" ); }
2.左移运算符重载和递增运算符重载
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 50 51 52 53 #include <iostream> using namespace std ;class Person {public : Person(){ m_num = 0 ; } Person& operator ++() { m_num++; return *this ; } Person operator ++(int ) { Person tmp=*this ; m_num++; return tmp; } int m_num; }; ostream& operator <<(ostream& cout , Person p) { cout << p.m_num; return cout ; } void test01 () { Person p1; cout << ++p1 << endl ; cout << p1 << endl ; } void test02 () { Person p2; cout << p2++ << endl ; cout << p2 << endl ; } int main () { test01(); test02(); system("pause" ); }
继承 继承是面向对象三大特性之一,下级的成员有上级的共性,且有自己的特性,就可以用继承来减少代码。
1.基本语法
先用不继承的方式来展示代码
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 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 #include <iostream> using namespace std ;class python { public : void up () { cout << "这里是页面上方" << endl ; } void down () { cout << "这里是页面下方" << endl ; } void left () { cout << "这里是页面左方" << endl ; } void right () { cout << "这里是页面右方" << endl ; } void pythonvideo () { cout << "这里是python的视频" << endl ; } }; class C { public : void up () { cout << "这里是页面上方" << endl ; } void down () { cout << "这里是页面下方" << endl ; } void left () { cout << "这里是页面左方" << endl ; } void right () { cout << "这里是页面右方" << endl ; } void cvideo () { cout << "这里是C的视频" << endl ; } }; class java { public : void up () { cout << "这里是页面上方" << endl ; } void down () { cout << "这里是页面下方" << endl ; } void left () { cout << "这里是页面左方" << endl ; } void right () { cout << "这里是页面右方" << endl ; } void javavideo () { cout << "这里是java的视频" << endl ; } }; int main () { C a; python b; java c; a.down(); a.up(); a.left(); a.right(); a.cvideo(); cout << "-------------------------------" << endl ; b.down(); b.up(); b.left(); b.right(); b.pythonvideo(); cout << "-------------------------------" << endl ; c.down(); c.up(); c.left(); c.right(); c.javavideo(); system("pause" ); }
可以看到,存在大量的重复代码,用继承就可以减少重复代码。
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 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 #include <iostream> using namespace std ;class base { public : void up () { cout << "这里是页面上方" << endl ; } void down () { cout << "这里是页面下方" << endl ; } void left () { cout << "这里是页面左方" << endl ; } void right () { cout << "这里是页面右方" << endl ; } }; class python :public base{ public : void pythonvideo () { cout << "这里是python的视频" << endl ; } }; class C :public base{ public : void cvideo () { cout << "这里是C的视频" << endl ; } }; class java :public base{ public : void javavideo () { cout << "这里是java的视频" << endl ; } }; int main () { C a; python b; java c; a.down(); a.up(); a.left(); a.right(); a.cvideo(); cout << "-------------------------------" << endl ; b.down(); b.up(); b.left(); b.right(); b.pythonvideo(); cout << "-------------------------------" << endl ; c.down(); c.up(); c.left(); c.right(); c.javavideo(); system("pause" ); }
2.继承方式
有三种继承方式,public,private,protected、 看完这个图就差不多了。
3.继承中的对象模型
虽然父类的私有成员在子类还是无法访问,但是是会被继承下去的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 #include <iostream> using namespace std ;class father { public : int m_a; protected : int m_b; private : int m_c; }; class son :public father{ public : int m_d; }; int main () { cout << sizeof (son) << endl ; }
如何看son的成员呢,用vs的工具,在菜单栏vs2019中的Developer Command Prompt。
先进入cpp的文件目录下,然后
cl /d1 reportSingleClassLayout查看的类名 所属文件名
就可以看成员结构了。
4.继承中构造和析构顺序
子类继承父类后,当创建子类对象,也会调用父类的构造函数,问题:父类和子类的构造和析构顺序是谁先谁后?
当然是有父才有子咯,而且类似于类成员中有类成员,父类都是先构造,最后析构。
5.继承同名成员,静态成员处理方式
访问子类同名成员 直接访问即可
访问父类同名成员 需要加作用域
静态成员还可以通过类名进行访问
6.继承多个类
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 #include <iostream> using namespace std ;class father { public : int m_a=1 ; }; class mather { public : int m_b=0 ; }; class son :public father, public mather{ public : int m_d; }; int main () { son m; cout << m.m_a << endl ; cout << m.m_b << endl ; }
7.菱形继承
例子
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 #include <iostream> using namespace std ;class grandfather { public : int m_num=1 ; }; class father1 :public grandfather{}; class father2 :public grandfather{}; class son :public father1, public father2{ public : int m_d; }; int main () { son m; m.father1::m_num = 2 ; m.father2::m_num = 3 ; cout << m.father1::m_num<< endl ; cout << m.father1::m_num << endl ; }
可以看到,m.father1::m_num = 2; m.father2::m_num = 3;,都是指的同一个东西,导致资源浪费以及毫无意义。这时候就可以用虚继承了。
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 #include <iostream> using namespace std ;class grandfather { public : int m_num=1 ; }; class father1 :virtual public grandfather{}; class father2 :virtual public grandfather{}; class son :public father1, public father2{ public : int m_d; }; int main () { son m; m.father1::m_num = 2 ; m.father2::m_num = 3 ; cout << m.father1::m_num<< endl ; cout << m.father1::m_num << endl ; }
在继承前面加个virtual,就行了,实质就变为了用偏移,可以用vs工具去看看。
多态 c++的第三个特征,多态
多态分为两类
静态多态: 函数重载 和 运算符重载属于静态多态,复用函数名
动态多态: 派生类和虚函数实现运行时多态
静态多态和动态多态区别:
静态多态的函数地址早绑定 - 编译阶段确定函数地址
动态多态的函数地址晚绑定 - 运行阶段确定函数地址
1.多态的基本概念
多态满足条件:
多态使用:父类指针或引用指向子类对象
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 #include <iostream> using namespace std ;class Animal { public : virtual void speak () { cout << "this is Animal" << endl ; } }; class Dog :public Animal{ public : void speak () { cout << "this is dog" << endl ; } }; void func (Animal& animal) { animal.speak(); } void test01 () { Dog dog; func(dog); } void test02 () { Animal* animal = new Dog; animal->speak(); delete animal; } int main () { test01(); test02(); system("pause" ); }
2.纯虚函数和抽象类
在多态中,通常父类中虚函数的实现是毫无意义的,主要都是调用子类重写的内容,因此可以将虚函数改为纯虚函数
纯虚函数语法:virtual 返回值类型 函数名 (参数列表)= 0 ;
当类中有了纯虚函数,这个类也称为==抽象类==
抽象类特点:
无法实例化对象
子类必须重写抽象类中的纯虚函数,否则也属于抽象类
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 #include <iostream> using namespace std ;class Father { public : virtual void func () = 0 ; }; class Son :public Father{ public : void func () { cout << "func函数" << endl ; } }; void test01 () { Son s; s.func(); } int main () { test01(); system("puase" ); }
3.虚析构和纯虚析构
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 50 51 52 53 54 55 #include <iostream> using namespace std ;class Father { public : virtual void func () = 0 ; virtual ~Father() = 0 ; }; Father::~Father() { } class Son :public Father{ public : Son(int num) { m_num = new int (num); } void func () { cout << "num is " << m_num << endl ; } ~Son() { if (m_num != NULL ) { delete m_num; m_num = NULL ; cout << "son 析构函数" << endl ; } } int *m_num; }; void test01 () { Father* father = new Son(1 ); delete father; } int main () { test01(); system("pause" ); }
文件 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 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 #include <iostream> #include <fstream> #include <string> using namespace std ;void test01 (ifstream& ifs) { char buf[100 ] = { 0 }; while (ifs>>buf) { cout << buf << endl ; } } void test02 (ifstream& ifs) { char buf[100 ] = { 0 }; while (ifs.getline(buf,sizeof (buf))) { cout << buf << endl ; } } void test03 (ifstream& ifs) { string buf; while (getline(ifs,buf)) { cout << buf << endl ; } } void test04 (ifstream& ifs) { char c; while ((c = ifs.get()) != EOF) { cout << c; } } int main () { ofstream ofs1; ofs1.open("txt.txt" , ios::trunc); ofs1 << "姓名:张三" << endl ; ofs1 << "性别:男" << endl ; ofs1 << "年龄:18" << endl ; ofs1.close(); ifstream ifs2; ifs2.open("txt.txt" , ios::in); if (!ifs2.is_open()) { cout << "文件打开失败" << endl ; return 0 ; } test04(ifs2); ifs2.close(); system("pause" ); }
职工管理系统 跟着写了写,还不错。
workerManager.h
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 #pragma once #include <iostream> #define FILENAME "empFile.txt" #include "worker.h" using namespace std ;class WorkerManager { public : WorkerManager(); void Showmenu () ; void AddEmp () ; void ShowEmp () ; void GetEmpNum () ; void EmptoFile () ; void Savefile () ; int IsExist (int id) ; void DeleteEmp () ; void UpdateEmp () ; void FindEmp () ; void SortEmp () ; void ClearFile () ; ~WorkerManager(); int m_Empnum=0 ; bool m_FileEmpty; Worker** m_EmpArray; };
workerManager.cpp
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 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 #include "workerManager.h" #include "employee.h" #include "boss.h" #include "manager.h" #include <fstream> WorkerManager::WorkerManager() { ifstream ifs; char ch; ifs.open(FILENAME, ios::in); ifs >> ch; if (!ifs.is_open()) { m_FileEmpty = true ; m_Empnum = 0 ; this ->m_EmpArray = NULL ; ifs.close(); } else if (ifs.eof()) { m_FileEmpty = true ; m_Empnum = 0 ; this ->m_EmpArray = NULL ; ifs.close(); } else { GetEmpNum(); EmptoFile(); } } WorkerManager::~WorkerManager() { if (m_EmpArray != NULL ) { for (int i = 0 ; i < m_Empnum; i++) { delete m_EmpArray[i]; } delete [] m_EmpArray; } } void WorkerManager::Showmenu () {cout << "********************************************" << endl ;cout << "********* 欢迎使用职工管理系统! **********" << endl ;cout << "************* 0.退出管理程序 *************" << endl ;cout << "************* 1.增加职工信息 *************" << endl ;cout << "************* 2.显示职工信息 *************" << endl ;cout << "************* 3.删除离职职工 *************" << endl ;cout << "************* 4.修改职工信息 *************" << endl ;cout << "************* 5.查找职工信息 *************" << endl ;cout << "************* 6.按照编号排序 *************" << endl ;cout << "************* 7.清空所有文档 *************" << endl ;cout << "********************************************" << endl ;cout << endl ;} void WorkerManager::AddEmp () { cout << "请输入要添加职工的数量" << endl ; int addnum = 0 ; int i; cin >> addnum; if (addnum > 0 ) { int newsize = m_Empnum + addnum; Worker** newtmp = new Worker * [newsize]; if (this ->m_EmpArray != NULL ) { for (i = 0 ; i < m_Empnum; i++) { newtmp[i] = m_EmpArray[i]; } } for (i = 0 ; i < addnum; i++) { int id; string name; int jobid; cout << "请输入第 " << i + 1 << " 个新职工编号:" << endl ; cin >> id; cout << "请输入第 " << i + 1 << " 个新职工名称:" << endl ; cin >> name; cout << "请选择该职工的岗位:" << endl ; cout << "1、普通职工" << endl ; cout << "2、经理" << endl ; cout << "3、老板" << endl ; cin >> jobid; Worker* worker = NULL ; switch (jobid) { case 1 : worker = new Employee(id, name, jobid); break ; case 2 : worker = new Manager(id, name, jobid); break ; case 3 : worker = new Boss(id, name, jobid); break ; default : break ; } newtmp[m_Empnum + i] = worker; } delete this ->m_EmpArray; this ->m_EmpArray = NULL ; this ->m_EmpArray = newtmp; this ->m_Empnum = newsize; m_FileEmpty = false ; cout << "成功添加" << addnum << "名新职工!" << endl ; } else { cout << "输入有错" << endl ; } Savefile(); system("pause" ); system("cls" ); } void WorkerManager::ShowEmp () { if (this ->m_Empnum==0 ) { cout << "没有一个职工" << endl ; } else { int i; for (i = 0 ; i < m_Empnum; i++) { this ->m_EmpArray[i]->showInfo(); } } system("pause" ); system("cls" ); } void WorkerManager::GetEmpNum () { ifstream ifs; ifs.open(FILENAME, ios::in); int id; string name; int jobid; while (ifs >> id && ifs >> name && ifs >> jobid) { m_Empnum++; } ifs.close(); } void WorkerManager::EmptoFile () { ifstream ifs; ifs.open(FILENAME, ios::in); int id; int i=0 ; string name; int jobid; Worker** newtmp = new Worker * [m_Empnum]; while (ifs >> id && ifs >> name && ifs >> jobid) { Worker* worker = NULL ; if (jobid == 1 ) { worker = new Employee(id, name, jobid); } else if (jobid == 2 ) { worker = new Manager(id, name, jobid); } else { worker = new Boss(id, name, jobid); } newtmp[i] = worker; i++; } this ->m_EmpArray = newtmp; m_FileEmpty = false ; ifs.close(); } void WorkerManager::Savefile () { int i; ofstream ofs; ofs.open(FILENAME, ios::out); for (i = 0 ; i < m_Empnum; i++) { ofs << this ->m_EmpArray[i]->m_Id << " " << this ->m_EmpArray[i]->m_Name << " " << this ->m_EmpArray[i]->m_JobId << endl ; } ofs.close(); } int WorkerManager::IsExist (int id) { int i; for (i = 0 ; i < m_Empnum; i++) { if (m_EmpArray[i]->m_Id == id) { return i; } } return -1 ; } void WorkerManager::DeleteEmp () { if (this ->m_FileEmpty) { cout << "文件不存在或记录为空!" << endl ; } else { int id; int index; int i; cout << "请输入你要删除的职工编号" << endl ; cin >> id; index = IsExist(id); if (index != -1 ) { for (i = index; i < m_Empnum-1 ; i++) { m_EmpArray[i] = m_EmpArray[i + 1 ]; } m_Empnum--; Savefile(); cout << "删除成功" << endl ; } else { cout << "没有查到该职员" << endl ; } } system("pause" ); system("cls" ); } void WorkerManager::UpdateEmp () { if (this ->m_FileEmpty) { cout << "文件不存在或记录为空!" << endl ; } else { int id; int index; int i; cout << "请输入你要修改的职工编号" << endl ; cin >> id; index = IsExist(id); if (index != -1 ) { int newid; string newname; int newjobid; cout << "请输入修改的新职工编号:" << endl ; cin >> newid; cout << "请输入修改的新职工名称:" << endl ; cin >> newname; cout << "请修改该职工的岗位:" << endl ; cout << "1、普通职工" << endl ; cout << "2、经理" << endl ; cout << "3、老板" << endl ; cin >> newjobid; m_EmpArray[index]->m_Id = newid; m_EmpArray[index]->m_Name = newname; m_EmpArray[index]->m_JobId = newjobid; Savefile(); cout << "修改成功" << endl ; } else { cout << "没有查到该职员" << endl ; } } system("pause" ); system("cls" ); } void WorkerManager::FindEmp () { if (this ->m_FileEmpty) { cout << "文件不存在或记录为空!" << endl ; } else { int id; int index; cout << "请输入你要查找的职工编号" << endl ; cin >> id; index = IsExist(id); if (index != -1 ) { this ->m_EmpArray[index]->showInfo(); } else { cout << "没有查到该职员" << endl ; } } system("pause" ); system("cls" ); } void WorkerManager::SortEmp () { if (this ->m_FileEmpty) { cout << "文件不存在或记录为空!" << endl ; } else { cout << "请选择排序方式: " << endl ; cout << "1、按职工号进行升序" << endl ; cout << "2、按职工号进行降序" << endl ; int select = 0 ; cin >> select; if (select==1 ) { int i, j; Worker* tmp = NULL ; for (i = 0 ; i < m_Empnum; i++) { for (j = 0 ; j < m_Empnum - 1 ; j++) { if (m_EmpArray[j]->m_Id > m_EmpArray[j + 1 ]->m_Id) { tmp = m_EmpArray[j + 1 ]; m_EmpArray[j + 1 ] = m_EmpArray[j]; m_EmpArray[j] = tmp; } } } Savefile(); cout << "排序成功" << endl ; } else if (select == 2 ) { int i, j, k; Worker* tmp = NULL ; for (i = 0 ; i < m_Empnum; i++) { k = i; for (j = i + 1 ; j < m_Empnum; j++) { if (m_EmpArray[j]->m_Id > m_EmpArray[k]->m_Id) { k = j; } } if (k != i) { tmp = m_EmpArray[i]; m_EmpArray[i] = m_EmpArray[k]; m_EmpArray[k] = tmp; } } Savefile(); cout << "排序成功" << endl ; } else { cout << "选择有误" << endl ; } } system("pause" ); system("cls" ); } void WorkerManager::ClearFile () { cout << "确认清空?" << endl ; cout << "1、确认" << endl ; cout << "2、返回" << endl ; int select = 0 ; cin >> select; if (select == 1 ) { ofstream ofs (FILENAME, ios::trunc) ; ofs.close(); if (m_EmpArray != NULL ) { for (int i = 0 ; i < m_Empnum; i++) { delete m_EmpArray[i]; } delete [] m_EmpArray; m_EmpArray = NULL ; m_Empnum = 0 ; m_FileEmpty = true ; } system("pause" ); system("cls" ); } else if (select == 2 ) { system("pause" ); system("cls" ); } }
worker.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 #pragma once #include <iostream> #include <string> using namespace std ;class Worker { public : virtual void showInfo () = 0 ; virtual string getJobName () = 0 ; int m_Id; string m_Name; int m_JobId; };
employee.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 #pragma once #include <iostream> #include <string> #include "worker.h" using namespace std ;class Employee :public Worker{ public : Employee(int Id, string Name, int JobId); virtual void showInfo () ; virtual string getJobName () ; };
employee.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 #include "employee.h" Employee::Employee(int Id, string Name, int JobId) { this ->m_Id = Id; this ->m_Name = Name; this ->m_JobId = JobId; } void Employee::showInfo () { cout << "职工编号: " << this ->m_Id << " \t职工姓名: " << this ->m_Name << " \t岗位:" << this ->getJobName() << " \t岗位职责:完成经理交给的任务" << endl ; } string Employee::getJobName () { return string ("员工" ); }
manager.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 #pragma once #include <iostream> #include <string> #include "worker.h" using namespace std ;class Manager :public Worker{ public : Manager(int Id, string Name, int JobId); virtual void showInfo () ; virtual string getJobName () ; };
manager.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 #include "manager.h" Manager::Manager(int Id, string Name, int JobId) { this ->m_Id = Id; this ->m_Name = Name; this ->m_JobId = JobId; } void Manager::showInfo () { cout << "职工编号: " << this ->m_Id << " \t职工姓名: " << this ->m_Name << " \t岗位:" << this ->getJobName() << " \t岗位职责:完成老板交给的任务" << endl ; } string Manager::getJobName () { return string ("经理" ); }
boss.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 #pragma once #include <iostream> #include <string> #include "worker.h" using namespace std ;class Boss :public Worker{ public : Boss(int Id, string Name, int JobId); virtual void showInfo () ; virtual string getJobName () ; };
boss.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 #include "boss.h" Boss::Boss(int Id, string Name, int JobId) { this ->m_Id = Id; this ->m_Name = Name; this ->m_JobId = JobId; } void Boss::showInfo () { cout << "职工编号: " << this ->m_Id << " \t职工姓名: " << this ->m_Name << " \t岗位:" << this ->getJobName() << " \t岗位职责:管理所有职工" << endl ; } string Boss::getJobName () { return string ("老板" ); }
main.cpp
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 <iostream> #include <string> #include "workerManager.h" using namespace std ;int main () { WorkerManager wm; int choice=0 ; while (1 ) { wm.Showmenu(); cout << "请输入您的选择:" << endl ; cin >> choice; switch (choice) { case 0 : exit (0 ); case 1 : wm.AddEmp(); break ; case 2 : wm.ShowEmp(); break ; case 3 : wm.DeleteEmp(); break ; case 4 : wm.UpdateEmp(); break ; case 5 : wm.FindEmp(); break ; case 6 : wm.SortEmp(); break ; case 7 : wm.ClearFile(); break ; default : system("cls" ); break ; } } system("pause" ); }