假期没网,是时候整理一下子笔记了
内存分区模型
程序运行前
- 代码区
- 共享(多次运行) 只读(防止修改)
- 全局区
- 全局变量、静态变量、常量(字符常量、其他常量)
- 该区域的数据在结束后由操作系统释放
程序运行后
- 栈区
- 局部变量、形参
- 由编译器管理开辟释放
- 不要返回局部变量的地址
- 堆区
- 由程序员分配释放,当程序员不释放时,由操作系统回收
- 主要利用new在堆区开辟内存
new操作符
#include <iostream>
using namespace std;
int * func()
{
int *p=new int(10);
return p;
}
void test01()
{
int *p=func();
cout<<*p<<endl;
delete p;
}
void test02()
{
int *arr=new int[10];
for(int i=0;i<10;i++)
{
arr[i]=i+100;
}
for(int i=0;i<10;i++)
{
cout<<arr[i]<<endl;
}
delete [] arr;
}
int main()
{
test01();
test02();
cout << "Hello world!" << endl;
return 0;
}
引用
- 给变量起别名
int & b=a
- 注意事项
- 引用必须初始化
- 引用初始化后不能修改
- 引用作函数参数
- 简化指针操作
- 引用做函数返回值
- 不要返回局部变量的引用
- 返回值是引用时可以作为左值
#include <iostream>
using namespace std;
int & test01()
{
int a=10;
return a;
}
//函数调用可以用做左值
int & test02()
{
static int a=10;
return a;
}
int main()
{
int & ref1=test01();
cout<<ref1<<endl;
cout<<ref1<<endl;
int & ref2=test02();
cout<<ref2<<endl;
test02()=1000;
cout<<ref2<<endl;
return 0;
}
- 引用的本质
- 引用本质是指针常量
- 常量引用
const int & b=10
合法- 限定形参(避免函数对参数进行修改)
函数
- 函数默认参数
- 如果某个位置有默认参数,则从该位置起从左到右必须有默认参数
#include <iostream>
using namespace std;
int func(int a ,int b=20 ,int c=30)
{
return a+b+c;
}
int main()
{
cout << "20 30 30"<<func(20,30,30)<< endl;
cout << "20"<<func(20)<< endl;
return 0;
}
- 函数声明和实现只能有一个默认参数
int fun(int a=10,int b=20);
int fun(int a=20,int b=20)
{
//二义性
}
- 函数占位参数
- 调用时必须填补参数
- 占位参数可以有默认参数
int fun(int a,int);
- 函数重载
- 同一作用域
- 函数名相同
- 函数参数类型、个数、顺序
- 返回值不能作为函数重载条件
#include <iostream>
using namespace std;
void func()
{
cout<<"func() run"<<endl;
}
void func(int a)
{
cout<<"func"<<a<<endl;
}
void func(double a)
{
cout<<"func"<<a<<endl;
}
void func(double a,int b)
{
cout<<"func"<<a<<b<<endl;
}
void func(int a,double b)
{
cout<<"func"<<a<<b<<endl;
}
int main()
{
func();
func(10);
func(3.14);
func(3.14,10);
func(10,3.14);
return 0;
}
- 引用作为函数重载条件
#include <iostream>
using namespace std;
void func(int &a)
{
cout<<"func"<<a<<endl;
}
void func( const int &a)
{
cout<<"func const"<<a<<endl;
}
int main()
{
int a=10;
func(a);
func(10);
return 0;
}
- 函数重载默认参数
函数重载尽量不要设置默认参数
void func2(int a)
{
cout<<"func2 a"<<a<<endl;
}
void func2(int a,int b=10)
{
cout<<"func2 ab"<<a<<endl;
}
面向对象编程
封装
- 封装的意义
- 将属性和行为作为一个整体,表现生活中的事物
- 将属性和行为加以权限控制
#include <iostream>
using namespace std;
const double PI =3.14;
//设计一个圆类,求圆的周长
class Circle
{
public:
int m_r;
// 获取圆的周长
double calculateZC()
{
return 2*PI*m_r;
}
};
int main()
{
//创建对象
Circle c1;
c1.m_r=10;
cout<<"圆的周长"<<c1.calculateZC()<<endl;
return 0;
}
设计学生类 显示姓名学号
#include <iostream>
#include <string>
using namespace std;
class Student
{
public:
string name;
string m_id;
void setname(string Name)
{
name=Name;
}
void setid(string id)
{
m_id=id;
}
void showdata()
{
cout<<"姓名"<<name<<"\t学号"<<m_id<<endl;
}
};
int main()
{
Student s1,s2;
s1.name="孙彦东";
s1.m_id="1709715010";
s1.showdata();
s2.setname("张三");
s2.setid("170971504");
s2.showdata();
return 0;
}
- 访问权限
- public
- protected
- private
- struct class
- struct 默认权限是public class是private
- 成员属性私有化
#include <iostream>
#include <string>
using namespace std;
class Person
{
private:
//rw
string m_name;
//r
int m_Age;
//w
string m_Lover;
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)
{
m_Age=0;
cout<<"error"<<endl;
return;
}
m_Age=age;
}
void setLover(string name)
{
m_Lover=name;
}
void showperson()
{
cout<<m_name<<m_Age<<m_Lover<<endl;
}
};
int main()
{
Person p;
p.setName("三");
p.setAge(25);
cout<<p.getAge()<<endl;
p.setLover("四") ;
p.showperson();
return 0;
}
练习 cube 面积体积 判断立方体是否相同
#include <iostream>
#include <string>
using namespace std;
class Cube
{
private:
int m_L;
int m_W;
int m_H;
public:
void setInit(int L,int W,int H)
{
m_L=L;
m_W=W;
m_H=H;
}
int Get_L()
{
return m_L;
}
int Get_W()
{
return m_W;
}
int Get_H()
{
return m_H;
}
int calculateV()
{
return m_L*m_W*m_H;
}
int calculateS()
{
return 2*m_L*m_H+2*m_W*m_L+2*m_W*m_H;
}
bool isName2(Cube &c2)
{
if(Get_L()==c2.Get_L()&&Get_W()==c2.Get_W()&&Get_H()==c2.Get_H())
{
return true;
}
else
return false;
}
};
bool isName(Cube &c1,Cube&c2)
{
if(c1.Get_L()==c2.Get_L()&&c1.Get_W()==c2.Get_W()&&c1.Get_H()==c2.Get_H())
{
return true;
}
else
return false;
}
int main()
{
Cube c1,c2;
c1.setInit(10,10,10);
c2.setInit(10,10,10);
cout<<"面积"<<c1.calculateS()<<"体积"<<c1.calculateV()<<endl;
cout<<isName(c1,c2);
cout<<c1.isName2(c2)<<endl;
return 0;
}
点与圆的关系
#include <iostream>
using namespace std;
class Point
{
private:
int m_X;
int m_Y;
public:
void setInit(int x,int y)
{
m_X=x;
m_Y=y;
}
int getX()
{
return m_X;
}
int getY()
{
return m_Y;
}
};
class Circle
{
private:
int m_r;
Point m_Center;
public:
void setR(int r)
{
m_r=r;
}
int getR()
{
return m_r;
}
void setCenter(Point center)
{
m_Center=center;
}
Point getCenter()
{
return m_Center;
}
};
void NodeCircle(Circle& c,Point &p)
{
int dis=(p.getX()-c.getCenter().getX())*(p.getX()-c.getCenter().getX())+
(p.getY()-c.getCenter().getY())*(p.getY()-c.getCenter().getY());
int cdis=c.getR()*c.getR();
if(dis==cdis)
{
cout<<"点在圆上"<<endl;
}
if(dis>cdis)
{
cout<<"点在圆外"<<endl;
}
if(dis<cdis)
{
cout<<"点在圆内"<<endl;
}
}
int main()
{
Point p;
p.setInit(10,0);
Circle c;
c.setR(10);
c.setCenter(p);
p.setInit(10,10);
NodeCircle(c,p);
p.setInit(10,9);
NodeCircle(c,p);
p.setInit(10,11c);
NodeCircle(c,p);
return 0;
}
分头文件书写
- Point.h
#ifndef POINT_H
#define POINT_H
#include <iostream>
using namespace std;
class Point
{
private:
int m_X;
int m_Y;
public:
void setInit(int x,int y);
int getX();
int getY();
};
#endif // POINT_H
- Point.cpp
#include "Point.h"
void Point::setInit(int x,int y)
{
m_X=x;
m_Y=y;
}
int Point::getX()
{
return m_X;
}
int Point::getY()
{
return m_Y;
}
- Circle.h
#ifndef CIRCLE_H
#define CIRCLE_H
#include "Point.h"
class Circle
{
private:
int m_r;
Point m_Center;
public:
void setR(int r);
int getR();
void setCenter(Point center);
Point getCenter();
};
#endif // CIRCLE_H
- Circle.cpp
#include "Circle.h"
void Circle::setR(int r)
{
m_r=r;
}
int Circle::getR()
{
return m_r;
}
void Circle::setCenter(Point center)
{
m_Center=center;
}
Point Circle::getCenter()
{
return m_Center;
}
对象的初始化和清理
- 构造和析构
- 构造函数:主要作用是创建对象时为成员属性赋值,由编译器调用,可以重载
- 析构函数:对象销毁前系统自动调用,执行一些清理工作
Person()
{
cout<<"构造函数调用"<<endl;
}
~Person()
{
cout<<"析构函数调用"<<endl;
}
- 构造函数分类和调用
- 无参构造(默认) 有参构造
- 普通构造 拷贝构造
#include <iostream>
using namespace std;
class Person
{
public:
int age;
Person()
{
cout<<"默认构造函数调用"<<endl;
}
Person(int a)
{
age=a;
cout<<"有参构造函数调用"<<a<<endl;
}
//拷贝构造函数
Person(const Person & p)
{
age=p.age;
cout<<"拷贝构造函数调用"<<endl;
}
~Person()
{
cout<<"析构函数调用"<<endl;
}
};
int main()
{
//括号法
Person p; //默认构造
Person p1(10);//有参构造
Person p2(p1);//拷贝构造
//显示法
Person pp;
Person pp1=Person(10);
Person pp2=Person(pp1);
//不要用拷贝构造初始化匿名对象
//隐式转换法
Person ppp1=10;
Person ppp2=ppp1;
return 0;
}
- 拷贝构造函数调用时机
- 用已有对象创建新的对象
- 值传递
- 以值的方式返回局部对象
#include <iostream>
using namespace std;
class Person
{
public:
int age;
Person()
{
cout<<"默认构造函数调用"<<endl;
}
Person(int a)
{
age=a;
cout<<"有参构造函数调用"<<a<<endl;
}
//拷贝构造函数
Person(const Person & p)
{
age=p.age;
cout<<"拷贝构造函数调用"<<endl;
}
~Person()
{
cout<<"析构函数调用"<<endl;
}
};
void copyfunc(Person p)
{
cout<<"copyfunc调用"<<endl;
}
Person dowork()
{
Person p1(10);
cout<<"dowork调用"<<endl;
return p1;
}
void test()
{
Person p=dowork();
}
int main()
{
//Person p(10);
//copyfunc(p);
test();
return 0;
}
- 构造函数调用规则
- 默认构造(空实现)、析构函数(空实现)、拷贝构造(值拷贝)
- 如果用户有参数构造,则C++不提供默认构造,但会提供拷贝构造
- 如果用户有拷贝构造,则C++不会提供其他构造函数
- 深拷贝和浅拷贝
- 浅拷贝:简单幅值 //堆区内存重复释放
- 深拷贝:重新申请空间,进行拷贝操作
如果有属性在堆区开辟时,一定要自己提供拷贝构造函数,防止浅拷贝带来的问题
#include <iostream>
using namespace std;
class Person
{
public:
int age;
int * m_Hight;
Person()
{
cout<<"默认构造函数调用"<<endl;
}
Person(int a,int height)
{
age=a;
m_Hight=new int(height);
cout<<"有参构造函数调用"<<a<<endl;
}
Person(const Person & p)
{
age=p.age;
m_Hight=new int(*p.m_Hight);
//浅拷贝m_Hight=p.m_Hight;
cout<<"深拷贝构造函数调用"<<endl;
}
~Person()
{
//将堆区数据释放
if(m_Hight!=NULL)
{
delete m_Hight;
m_Hight=NULL;
}
cout<<"析构函数调用"<<endl;
}
};
int main()
{
Person p1(10,160);
cout<<p1.age<<*p1.m_Hight<<p1.m_Hight<<endl;
Person p2(p1);
cout<<p2.age<<*p2.m_Hight<<p2.m_Hight<<endl;
return 0;
}
- 初始化列表
Person():m_A(10),m_B(20),m_C(30)
{
}
Person(int a,int b,int c):m_A(a),m_B(b),m_C(c)
{
}
- 类对象作为类成员
-
当其他类对象作为本类成员,构造时先构造类对象,再构造自身
-
析构顺序 先析构自身,在析构内部成员
#include <iostream>
#include <string>
using namespace std;
class Phone
{
public:
string m_Pname;
Phone(string name)
{
m_Pname=name;
cout<<"手机构造"<<endl;
}
~Phone()
{
cout<<"手机析构"<<endl;
}
};
class Person
{
public:
string m_name;
Phone m_phone;
Person(string name,string pname):m_name(name),m_phone(pname)
{
cout<<"人构造"<<endl;
}
~Person()
{
cout<<"人析构"<<endl;
}
};
int main()
{
Person p("zhang","Apple");
cout<<p.m_name<<p.m_phone.m_Pname<<endl;
return 0;
}
- 静态成员
- 静态成员
-
所有对象共享同一份数据
-
编译阶段分配内存
-
类内声明,类外初始化
-
访问方式
- 类名访问
- 对象访问
-
#include <iostream>
using namespace std;
class Person
{
public:
static int m_a;
};
int Person::m_a=100;
int main()
{
Person p;
cout<<p.m_a<<endl;
Person p2;
p2.m_a=200;
cout<<p.m_a<<endl;
cout<<Person::m_a<<endl;
return 0;
}
- 静态成员函数
- 静态成员函数只能访问静态成员变量
- 访问方式
- 对象访问
- 类名访问
#include <iostream>
using namespace std;
class Person
{
public:
static int m_a;
//int m_b;
static void func()
{
cout<<"static void func run"<<endl;
//m_b=100;
m_a=200;
}
};
int Person::m_a=100;
int main()
{
cout<<Person::m_a<<endl;
//对象访问
Person p;
p.func();
//类名访问
Person::func();
cout<<Person::m_a<<endl;
return 0;
}
- C++对象模型和this指针
- 空对象占用1字节,区分其他空对象
cout<<"sizeof "<<sizeof(p)<<endl;
- 非静态成员变量属于类的对象上
class Person
{
int m_a;
static int m_b;
void func()
{
}
};
int Person::m_b=100;
int main()
{
Person p;
cout<<"sizeof "<<sizeof(p)<<endl;
return 0;
}
- this指针:指向被调用成员函数所属的对象
- 隐含在每一个非静态成员函数之中
- 在类非静态成员函数中返回对象本身,可以使用
return *this
(左值)
链式编程思想
#include <iostream>
using namespace std;
class Person
{
public:
int age;
Person(int age)
{
this->age=age;
}
Person& PersonAdd(Person& p)
{
this->age+=p.age;
return *this;
}
};
int main()
{
Person p(10);
cout<<p.age<<endl;
Person p1(10);
p.PersonAdd(p1);
cout<<p.age<<endl;
p.PersonAdd(p1).PersonAdd(p1);
cout<<p.age<<endl;
return 0;
}
- 空指针调用成员函数
#include <iostream>
using namespace std;
class Person
{
public:
int age;
void showClassName()
{
cout<<"this is Person class"<<endl;
}
void showPersonAge()
{
if(this==NULL) return;
cout<<age<<endl;
}
};
void test01()
{
Person* p=NULL;
p->showClassName();
//报错
p->showPersonAge();
}
int main()
{
test01();
return 0;
}
- const 修饰成员函数
- 常函数
- 常函数:常函数不能修改成员属性
- 成员函数加关键字mutable后,常函数中依然可以修改
- 常对象
- 常对象只能调用常函数
#include <iostream>
using namespace std;
class Person
{
public:
Person():m_a(10){}
int m_a;
mutable int m_b;
void showPerson() const //本质修饰this
{
//this->m_a=100;
//this 指针是一个常量指针
//const Person *const this
this->m_b=100;
}
void func()
{
}
};
void test01()
{
Person p;
p.showPerson();
}
void test02()
{
const Person p1;
p1.m_b=100;
//常对象只能调用常函数
p1.showPerson();
//p1.func();
}
int main()
{
test01();
test02();
return 0;
}
友元
- 全局函数做友元
#include <iostream>
#include <string>
using namespace std;
class Builing
{
friend void good(Builing& builing);
public:
string m_Sittingroom;
private:
string bedroom;
public:
Builing()
{
m_Sittingroom="客厅";
bedroom="卧室";
}
};
void good(Builing& builing)
{
cout<<"at"<<builing.m_Sittingroom<<endl;
cout<<"at"<<builing.bedroom<<endl;
}
void test01()
{
Builing builing;
good(builing);
}
int main()
{
test01();
return 0;
}
- 友元类
#include <iostream>
#include <string>
using namespace std;
class Builing
{
friend class good;
public:
string m_Sittingroom;
private:
string bedroom;
public:
Builing()
{
m_Sittingroom="客厅";
bedroom="卧室";
}
};
class good
{
public:
Builing *builing;
void visit()
{
cout<<"at"<<builing->m_Sittingroom<<endl;
cout<<"at"<<builing->bedroom<<endl;
}
good()
{
builing=new Builing;
}
};
void test01()
{
good gg;
gg.visit();
}
int main()
{
test01();
return 0;
}
- 成员函数做友元
friend void good::visit()
运算符重载
加号运算符重载
Person personaddper(Person &p)
Person operator+ (Person &p)
- 成员函数重载
class Person
{
public:
int m_a;
int m_b;
Person operator+(Person &p)
{
Person temp;
temp.m_a=this->m_a+p.m_a;
temp.m_b=this->m_b+p.m_b;
return temp;
}
};
void test01()
{
Person p1;
p1.m_a=10;
p1.m_b=10;
Person p2;
p2.m_a=10;
p2.m_b=10;
Person p3=p1+p2;
cout<<p3.m_a<<p3.m_b<<endl;
}
- 全局函数重载
Person operator+(Person &p1,Person& p2)
{
Person temp;
temp.m_a=p1.m_a+p2.m_a;
temp.m_b=p1.m_b+p2.m_b;
return temp;
}
void test02()
{
Person p1;
p1.m_a=10;
p1.m_b=10;
Person p2;
p2.m_a=10;
p2.m_b=10;
Person p3=p1+p2;
cout<<p3.m_a<<p3.m_b<<endl;
}
- 函数重载(运算符重载)
Person+int
左移运算符重载
- 场景:对象输出
- 不会利用成员运算符重载<<运算符 ,只能利用全局函数重载左移运算符
链式编程思想
ostream & operator<<(ostream & cout,Person &p)
{
cout<<p.m_a<<p.m_b<<endl;
return cout;
}
//链式编程思想
void test01()
{
Person p;
p.m_a=10;
p.m_b=10;
cout<<p.m_a<<p.m_b<<endl;
cout<<p<<endl;
}
- 友元函数
- 重载左移运算符配合友元可以实现输出自定义数据类型
#include <iostream>
using namespace std;
class Person
{
private:
int m_a;
int m_b;
//不会利用成员函数重载左移运算符
/*void operator<<()
{
}*/
friend ostream & operator<<(ostream & cout,Person &p);
public:
Person():m_a(10),m_b(10)
{
}
};
ostream & operator<<(ostream & cout,Person &p)
{
cout<<p.m_a<<p.m_b<<endl;
return cout;
}
//链式编程思想
void test01()
{
Person p;
cout<<p<<endl;
}
int main()
{
test01();
return 0;
}
递增运算符重载
#include <iostream>
using namespace std;
class MyInteger
{
public:
MyInteger()
{
m_Num=0;
}
private:
int m_Num;
friend ostream & operator<< (ostream& os,const MyInteger &myint);
public:
//前置递增
MyInteger& operator++()
{
m_Num++;
return *this;
}
//后置递增
MyInteger operator++(int) //int占位参数
{
//先记录结构
MyInteger temp=*this;
m_Num++;
return temp;
}
};
ostream & operator<< (ostream& os,const MyInteger &myint)
{
os<<myint.m_Num<<endl;
return os;
}
void test01()
{
MyInteger myint;
cout<<myint<<endl;
cout<<++myint<<endl; //temp出来的时候被释放无人接收
}
void test02()
{
MyInteger myint;
cout<<myint<<endl;
cout<<(myint++) <<endl;
}
int main()
{
test01();
test02();
cout << "Hello world!" << endl;
return 0;
}
幅值运算符重载
- C++编译器默认添加一个赋值运算符operator=对属性进行值拷贝
#include <iostream>
using namespace std;
class Person
{
private:
int *m_age;
friend ostream & operator<<(ostream & cout,Person &p);
public:
Person(int age)
{
m_age=new int(age);
}
~Person()
{
if(m_age!=NULL)
{
delete m_age;
m_age=NULL;
}
}
Person& operator=(Person &p)
{
if(m_age!=NULL)
{
delete m_age;
m_age=NULL;
}
m_age=new int(*p.m_age);
return *this;
}
};
ostream & operator<<(ostream & cout,Person &p)
{
cout<<*p.m_age<<endl;
return cout;
}
void test01()
{
Person p1(18);
Person p2(20);
Person p3(10);
cout<<p1<<endl;
cout<<p2<<endl;
cout<<p3<<endl;
p3=p2=p1;
cout<<p3<<endl;
}
int main()
{
test01();
return 0;
}
关系运算符重载
#include <iostream>
#include <string>
using namespace std;
class Person
{
private:
string m_name;
int m_age;
friend ostream & operator<<(ostream & cout,Person &p);
public:
Person(string name,int age):m_name(name),m_age(age)
{
}
bool operator==(Person& p)
{
if(p.m_age==m_age&&p.m_name==m_name)
{
return true;
}
return false;
}
bool operator!=(Person& p)
{
if(p.m_age==m_age&&p.m_name==m_name)
{
return false;
}
return true;
}
};
ostream & operator<<(ostream & cout,Person &p)
{
cout<<p.m_name<<p.m_age<<endl;
return cout;
}
void test01()
{
Person p1("tom",18);
Person p2("tom",20);
cout<<p1<<endl;
cout<<p2<<endl;
cout<<(p1==p2)<<endl;
}
int main()
{
test01();
return 0;
}
函数调用运算符重载
- 函数调用运算符() 仿函数 没有固定的写法非常灵活
#include <iostream>
#include <string>
using namespace std;
class MyPrint
{
public:
void operator()(string test)
{
cout<<test<<endl;
}
//与函数调用非常相似
};
class MyAdd
{
public:
int operator()(int num1,int num2)
{
return num1+num2;
}
};
void test01()
{
MyPrint myprint;
myprint("Hello World");
}
void test02()
{
MyAdd myadd;
int ret=myadd(100,100);
cout<<ret<<endl;
}
//匿名函数对象
void test03()
{
cout<<MyAdd()(100,100)<<endl;
}
int main()
{
test01();
test02();
test03();
return 0;
}
继承
语法
- 不使用继承
class Java
{
public:
void header()
{
cout<<"公共头部"<<endl;
}
void footer()
{
cout<<"公共底部"<<endl;
}
void left()
{
cout<<"公共左侧"<<endl;
}
void content()
{
cout<<"内容"<<endl;
}
};
void test01()
{
Java ja;
ja.header();
ja.footer();
ja.left();
ja.content();
}
- 使用继承
class BasePage
{
public:
void header()
{
cout<<"公共头部"<<endl;
}
void footer()
{
cout<<"公共底部"<<endl;
}
void left()
{
cout<<"公共左侧"<<endl;
}
};
class Java:public BasePage
{
public:
void content()
{
cout<<"内容"<<endl;
}
};
继承方式
private 都访问不到
- 公共继承
不变
- 保护继承
都变成保护
- 私有继承
都变成私有
继承的对象模型
- 父类中所有的非静态成员属性都会被子类继承下去
#include <iostream>
using namespace std;
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"<<sizeof(Son)<<endl;
}
int main()
{
test01();
return 0;
}
继承中构造和析构顺序
- 子类继承父类后,当创建子类对象,也会调用父类的构造函数
先后顺序验证
#include <iostream>
using namespace std;
class Base
{
public:
Base()
{
cout<<"父类构造"<<endl;
}
~Base()
{
cout<<"父类析构"<<endl;
}
};
class Son:public Base
{
public:
Son()
{
cout<<"子类构造"<<endl;
}
~Son()
{
cout<<"子类析构"<<endl;
}
};
void test01()
{
Son s;
}
int main()
{
test01();
return 0;
}
父类构造
子类构造
子类析构
父类析构
继承中同名成员
- 同名成员属性
cout<<s.m_a<<endl;
cout<<s.Base::m_a<<endl;
- 同名成员函数
#include <iostream>
using namespace std;
class Base
{
public:
int m_a;
Base()
{
m_a=100;
}
void func()
{
cout<<"base func"<<endl;
}
void func(int a)
{
cout<<"base func int a"<<endl;
}
};
class Son:public Base
{
public:
int m_a;
Son()
{
m_a=200;
}
~Son()
{
}
void func()
{
cout<<"Son func"<<endl;
}
};
void test01()
{
Son s;
cout<<s.m_a<<endl;
cout<<s.Base::m_a<<endl;
}
void test02()
{
Son s;
s.func();
s.Base::func();
s.Base::func(1);
}
int main()
{
test01();
test02();
return 0;
}
继承中同名静态成员处理
- 加作用域
son::base::m_a;
son访问 base作用域下的m_a
多继承语法
class zi:public fu,public fu2
- 不建议使用
class Son:public Base1,Public Base2
菱形继承
- 两个派生类继承同一个基类,另一个类同时继承两个派生类
- 问题:会产生二义性,实际只需要一份数据
//虚继承解决菱形继承问题;
//(虚基类指针)vbptr ->vbtable (虚基类表 记录偏移量)
#include <iostream>
using namespace std;
//虚继承
class Animal
{
public:
int m_age;
};
class Sheep:virtual public Animal
{
public:
};
class Tuo:virtual public Animal
{
public:
};
class SheepTuo:public Sheep,public Tuo
{
};
//虚继承解决菱形继承问题;
//(虚基类指针)vbptr ->vbtable (虚基类表 记录偏移量)
void test01()
{
SheepTuo st;
st.Sheep::m_age=18;
st.Tuo::m_age=28;
cout<<st.m_age<<endl;
}
int main()
{
test01();
return 0;
}
多态
多态概念
- 动态多态
- 派生类和虚函数实现运行时多态,运行阶段确定函数地址
条件:子类重写父类的虚函数 使用:使用父类引用,执行子类对象
#include <iostream>
using namespace std;
class Animal
{
public:
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();
}
void test01()
{
Cat cat;
Dog dog;
dospeak(dog);
dospeak(cat);
}
int main()
{
test01();
return 0;
}
- 多态原理剖析
//vfptr (虚函数指针)->vftable虚函数表 子类替换父类的虚函数地址
void test01()
{
cout<<sizeof(Animal)<<endl;
cout<<sizeof(Dog)<<endl;
cout<<sizeof(Cat)<<endl;
}
案例-计算器类
- 设计实现两个操作数进行运算的计算器类
优点:代码组织结构清晰,可读性强,利于扩展维护
普通实现
class Calculator
{
public:
int num1;
int num2;
int getResult(string oper)
{
if(oper=="+")
{
return num1+num2;
}
if(oper=="-")
{
return num1-num2;
}
if(oper=="*")
{
return num1*num2;
}
return -1;
}
protected:
private:
};
void test01()
{
Calculator c;
c.num1=10;
c.num2=10;
cout<<c.num1<<"+"<<c.num2<<"="<<c.getResult("+")<<endl;
cout<<c.num1<<"-"<<c.num2<<"="<<c.getResult("-")<<endl;
cout<<c.num1<<"*"<<c.num2<<"="<<c.getResult("*")<<endl;
}
多态实现
//利用多态实现
class Abstract
{
public:
int num1;
int num2;
virtual int getResult()
{
return 0;
}
};
class addcalculator:public Abstract
{
public:
virtual int getResult()
{
return num1+num2;
}
};
class subcalculator:public Abstract
{
public:
virtual int getResult()
{
return num1-num2;
}
};
class mulcalculator:public Abstract
{
public:
virtual int getResult()
{
return num1*num2;
}
};
void test02()
{
Abstract *abc=new addcalculator;
abc->num1=10;
abc->num2=10;
cout<<abc->num1<<"+"<<abc->num2<<"="<<abc->getResult()<<endl;
delete abc;
abc=new subcalculator;
abc->num1=10;
abc->num2=10;
cout<<abc->num1<<"-"<<abc->num2<<"="<<abc->getResult()<<endl;
delete abc;
abc=new mulcalculator;
abc->num1=10;
abc->num2=10;
cout<<abc->num1<<"*"<<abc->num2<<"="<<abc->getResult()<<endl;
delete abc;
}
纯虚函数 和抽象类
- 写法 virtual int hh() =0 纯虚函数-抽象类
抽象类:无法实例化,子类必须重写父类中的纯虚函数
class Base
{
public:
virtual void func()=0;
};
class Son:public Base
{
public:
void func()
{
cout<<"Hello"<<endl;
}
};
void test01()
{
Son s;
s.func();
Base* b=new Son;
b->func();
}
案例-制作饮品
煮水、冲泡、倒入,加辅料 (咖啡,茶叶)
class Abstract
{
public:
virtual void boil()=0;
virtual void Brew()=0;
virtual void PourInCup()=0;
virtual void PutSomething()=0;
void makeDrink()
{
boil();
Brew();
PourInCup();
PutSomething();
}
};
class coffee:public Abstract
{
public:
virtual void boil()
{
cout<<"boil"<<endl;
}
virtual void Brew()
{
cout<<"Brew"<<endl;
}
virtual void PourInCup()
{
cout<<"PourInCup"<<endl;
}
virtual void PutSomething()
{
cout<<"PutSomething"<<endl;
}
};
class Tea:public Abstract
{
public:
virtual void boil()
{
cout<<"boil---"<<endl;
}
virtual void Brew()
{
cout<<"Brew---"<<endl;
}
virtual void PourInCup()
{
cout<<"PourInCup---"<<endl;
}
virtual void PutSomething()
{
cout<<"PutSomething---"<<endl;
}
};
void dowork(Abstract *abs)
{
abs->makeDrink();
delete abs;
}
void test01()
{
dowork(new coffee);
dowork(new Tea);
}
虚析构,纯虚析构
- 语法
~p()
~p()=0
- 如果子类没有堆区数据,可以不写虚析构。有虚析构的也是抽象类
class Animal
{
public:
Animal()
{
cout<<"Animal()"<<endl;
}
/*virtual ~Animal()
{
cout<<"~Animal()"<<endl;
}*/
virtual ~Animal()=0;
virtual void Speak()=0;
};
//纯虚析构,需要声明+实现
Animal::~Animal()
{
cout<<"virtual ~Animal()"<<endl;
}
//利用虚析构可以实现 父类指针释放子类对象
class Cat:public Animal
{
public:
Cat(string name)
{
m_name=new string(name);
cout<<"cat()"<<endl;
}
~ Cat()
{
if(m_name!=NULL)
{
cout<<"~cat()"<<endl;
delete m_name;
m_name=NULL;
}
}
void Speak()
{
cout<<*m_name<<"小猫在说话"<<endl;
}
string * m_name;
};
void test01()
{
Animal *abs=new Cat("mao");
abs->Speak();
delete abs;
}
案例- 电脑组装
CPU 显卡 内存条
将每个零件封装出抽象基类,并提供不同的厂商生产的不同零件
创建电脑类提供电脑工作的函数,并且调用每个零件工作的接口
测试三台不同的电脑进行工作
class CPU
{
public:
virtual void calculate()=0;
};
class VideoCard
{
public:
virtual void display()=0;
};
class Memory
{
public:
virtual void storage()=0;
};
class Computer
{
public:
Computer(CPU* cpu,VideoCard *vc,Memory *mem)
{
m_cpu=cpu;
m_vc=vc;
m_mem=mem;
}
void work()
{
m_cpu->calculate();
m_vc->display();
m_mem->storage();
}
~Computer()
{
if(m_cpu!=NULL)
{
delete m_cpu;
m_cpu=NULL;
}
if(m_vc!=NULL)
{
delete m_vc;
m_vc=NULL;
}
if(m_mem!=NULL)
{
delete m_mem;
m_mem=NULL;
}
}
private:
CPU *m_cpu;
VideoCard *m_vc;
Memory * m_mem;
};
class InterCPU:public CPU
{
public:
virtual void calculate()
{
cout<<"InterCPU"<<endl;
}
};
class InterMemory:public Memory
{
public:
virtual void storage()
{
cout<<"InterMemory"<<endl;
}
};
class InterVideoCard:public VideoCard
{
public:
virtual void display()
{
cout<<"InterVideoCard"<<endl;
}
};
class LenovoCPU:public CPU
{
public:
virtual void calculate()
{
cout<<"LenovoCPU"<<endl;
}
};
class LenovoMemory:public Memory
{
public:
virtual void storage()
{
cout<<"LenovoMemory"<<endl;
}
};
class LenovoVideoCard:public VideoCard
{
public:
virtual void display()
{
cout<<"LenovoVideoCard"<<endl;
}
};
void test01()
{
CPU *intercpu=new InterCPU;
VideoCard * intervc=new InterVideoCard;
Memory * intermem=new InterMemory;
Computer *c1=new Computer(intercpu,intervc,intermem);
c1->work();
delete c1;
cout<<"--------------------"<<endl;
c1=new Computer(new LenovoCPU,new LenovoVideoCard,new LenovoMemory);
c1->work();
delete c1;
cout<<"--------------------"<<endl;
c1=new Computer(new LenovoCPU,new InterVideoCard,new LenovoMemory);
c1->work();
delete c1;
}
文件操作
头文件 fstream
- 文件分类
- 文本文件:ASCII
- 二进制文件:binary
- 文件操作
ofstream ifstream fstream
文本文件
- 写文件
- 包含头文件
- 创建流对象
- 打开文件
打开方式 | 解释 |
---|---|
ios::in | 为读文件而打开文件 |
ios::out | 为写文件而打开文件 |
ios::ate | 文件尾 |
ios::app | 追加写文件 |
ios::trunc | 文件存在,先删除再创建 |
ios::binary | 二进制 |
- 写数据
- 关闭文件
void test01()
{
//1.包含头文件
//2. 创建流对象
ofstream ofs;
ofs.open("text.txt",ios::out);
ofs<<"name sun"<<endl;
ofs<<"sex man"<<endl;
ofs<<"age 18"<<endl;
ofs.close();
}
- 读文件
void test02()
{
ifstream ifs;
ifs.open("text.txt",ios::in);
if(!ifs.is_open())
{
cout<<"fail"<<endl;
return;
}
char buf[1024]={0};
while(ifs>>buf)
{
cout<<buf<<endl;
}
ifs.close();
}
void test03()
{
ifstream ifs;
ifs.open("text.txt",ios::in);
if(!ifs.is_open())
{
cout<<"fail"<<endl;
return;
}
char buf[1024]={0};
while(ifs.getline(buf,sizeof(buf)))
{
cout<<buf<<endl;
}
ifs.close();
}
void test04()
{
ifstream ifs;
ifs.open("text.txt",ios::in);
if(!ifs.is_open())
{
cout<<"fail"<<endl;
return;
}
string buf;
while(getline(ifs,buf))
{
cout<<buf<<endl;
}
ifs.close();
}
void test05()
{
ifstream ifs;
ifs.open("text.txt",ios::in);
if(!ifs.is_open())
{
cout<<"fail"<<endl;
return;
}
char c;
while(c=ifs.get()!=EOF)
{
cout<<c;
}
ifs.close();
}
二进制
- 写文件
void test01()
{
ofstream ofs;
ofs.open("person.txt",ios::out|ios::binary);
Person p={"zhang",18};
ofs.write((const char *)&p,sizeof(Person));
ofs.close();
}
- 读文件
void test02()
{
ifstream ifs;
ifs.open("person.txt",ios::in|ios::binary);
if(!ifs.is_open())
{
cout<<"fail"<<endl;
return;
}
Person p;
ifs.read((char *)&p,sizeof(Person));
cout<<p.m_name<<p.m_age<<endl;
ifs.close();
}
职工管理系统
- 职工分类:普通员工、经理、老板 需要显示职工编号、姓名、岗位、职责
- 普通员工:完成员工交给的任务
- 经理职责:完成老板交给的任务,并下发任务给员工
- 老板:管理公司所有事务
- 功能
- 退出管理程序
- 增加职工信息:实现批量添加职工功能,将信息录入到文件中,职工信息为
:职工编号、姓名、部门编号 - 显示职工信息:显示公司内部所有职工信息
- 删除离职职工:删除指定职工
- 修改职工信息:按编号修改
- 查找职工信息:按照职工编号或姓名查找
- 按照编号排序
- 清空所有文档:清空文件中记录的所有职工信息
创建管理类
- 与用户的沟通菜单界面
- 对职工增删改查
- 与文件的读写操作
class WorkManager
{
public:
WorkManager();
virtual ~WorkManager();
protected:
private:
};
菜单功能
void WorkManager::Show_Menu()
{
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 WorkManager::Exitsystem()
{
cout<<"欢迎下次使用"<<endl;
system("pause");
system("cls");
}
创建职工类
- 创建职工抽象类
#ifndef WORKER_H
#define WORKER_H
#include <string>
using namespace std;
class worker
{
public:
//显示个人信息
virtual void showInfo()=0;
//获取岗位名称
virtual string getDeptName()=0;
int m_id;
string m_name;
int m_Deptid;
protected:
private:
};
#endif // WORKER_H
- 创建普通员工类
#ifndef EMPLOYEE_H
#define EMPLOYEE_H
#include "worker.h"
#include <string>
#include <iostream>
using namespace std;
class employee:public worker
{
public:
employee(int id,string name,int did);
virtual ~employee();
//显示个人信息
virtual void showInfo();
//获取岗位名称
virtual string getDeptName();
protected:
private:
};
#endif // EMPLOYEE_H
#include "employee.h"
employee::employee(int id,string name,int did)
{
this->m_id=id;
this->m_name=name;
this->m_Deptid=did;
}
employee::~employee()
{
//dtor
}
//显示个人信息
void employee::showInfo()
{
cout<<"职工编号:"<<this->m_id
<<"\t职工姓名:"<<this->m_name
<<"\t岗位:"<<this->getDeptName()
<<"\t岗位职责:完成经理交给的任务"<<endl;
}
//获取岗位名称
string employee::getDeptName()
{
return string("员工");
}
- 创建经理类
manager - 创建老板类
boss
添加职工
void WorkManager::Add_Emp()
{
cout<<"请输入添加职工数量"<<endl;
int addnum=0;
cin>>addnum;
if(addnum>0)
{
int newSize=this->m_EmpNum+addnum; //原来加新加的人
worker** newSpace =new worker*[newSize];
//将原来拷贝到新的
if(this->m_empArray!=NULL)
{
for(int i=0;i<this->m_EmpNum-1;i++)
{
newSpace[i]=this->m_empArray[i];
}
}
//批量添加职工
for(int i=0;i<addnum;i++)
{
int id;
string name;
int dselect;
cout<<"请输入第"<<i+1<<"个新职工编号"<<endl;
cin>>id;
cout<<"请输入第"<<i+1<<"个新职工姓名"<<endl;
cin>>name;
cout<<"请选择职工岗位"<<endl;
cout<<"1.普通职工"<<endl;
cout<<"2.经理"<<endl;
cout<<"3.老板"<<endl;
cin>>dselect;
worker * wk=NULL;
switch(dselect)
{
case 1:
wk=new employee(id,name,1);
break;
case 2:
wk=new manager(id,name,2);
break;
case 3:
wk=new boss(id,name,3);
break;
default:
break;
}
//保存到数组中
newSpace[i+this->m_EmpNum]=wk;
}
//释放原来控件
delete [] this->m_empArray;
//更改新空间指向
this->m_empArray=newSpace;
//更新新的职工人数
this->m_EmpNum=newSize;
cout<<"成功添加"<<addnum<<"名新职工"<<endl;
}
else
{
cout<<"输入有误"<<endl;
}
system("pause");
system("cls");
}
文件交互
- 写文件
void WorkManager::save()
{
ofstream ofs;
ofs.open(FILENAME,ios::out);//write
for(int i=0;i<this->m_EmpNum;i++)
{
ofs<<this->m_empArray[i]->m_id
<<this->m_empArray[i]->m_name
<<this->m_empArray[i]->m_Deptid<<endl;
}
ofs.close();
}
- 读文件
- 文件不存在
ifstream ifs;
ifs.open("FILENAME",ios::in);
if(!ifs.is_open())
{
cout<<"文件不存在"<<endl;
this->m_EmpNum=0;
this->m_empArray=NULL;
this->m_FileIsEmpty=true;
}
- 空文件
char ch;
ifs>>ch;
if(ifs.eof())
{
cout<<"文件为空"<<endl;
this->m_EmpNum=0;
this->m_empArray=NULL;
this->m_FileIsEmpty=true;
ifs.close();
return;
}
- 存在数据
int num=get_EmpNum();
cout<<"职工人数为:"<<num<<endl;
this->m_EmpNum=num;
this->m_empArray=new worker* [this->m_EmpNum];
this->init_Emp();
for(int i=0;i<this->m_EmpNum;i++)
{
cout<<this->m_empArray[i]->m_id<<" "
<<this->m_empArray[i]->m_name<<" "
<<this->m_empArray[i]->m_Deptid<<endl;
}
int WorkManager::get_EmpNum()
{
ifstream ifs;
ifs.open(FILENAME,ios::in);
int id;
string name;
int did;
int num=0;
while(ifs>>id&&ifs>>name&&ifs>>did)
{
num++;
}
return num;
}
void WorkManager::init_Emp()
{
ifstream ifs;
ifs.open(FILENAME,ios::in);
int id;
string name;
int did;
int index=0;
while(ifs>>id&&ifs>>name&&ifs>>did)
{
worker* wk=NULL;
if(did==1)
{
wk=new employee(id,name,did);
}
else if(did==2)
{
wk=new manager(id,name,did);
}
else if(did==3)
{
wk=new boss(id,name,did);
}
this->m_empArray[index]=wk;
index++;
}
ifs.close();
}
显示职工
void WorkManager::Show_Emp()
{
if(this->m_FileIsEmpty)
{
cout<<"文件不存在或记录为空!"<<endl;
}
else
{
for(int i=0;i<m_EmpNum;i++)
{
this->m_empArray[i]->showInfo();
}
}
system("pause");
system("cls");
}
删除职工
//职工是否存在
int WorkManager::IsExist(int id)
{
int index=-1;
for(int i=0;i<this->m_EmpNum;i++)
{
if(this->m_empArray[i]->m_id==id)
{
index=i;
break;
}
}
return index;
}
//删除职工
void WorkManager::delEmp()
{
if(this->m_FileIsEmpty)
{
cout<<"文件不存在或记录为空!"<<endl;
}
else
{
cout<<"请输入想要删除职工编号:"<<endl;
int id=0;
cin>>id;
int index=this->IsExist(id);
if(index!=-1)
{
for(int i=index;i<m_EmpNum-1;i++)
{
this->m_empArray[i]=this->m_empArray[i+1];
}
this->m_EmpNum--;
this->save();
cout<<"删除成功"<<endl;
}
else
{
cout<<"删除失败,未找到该职工"<<endl;
}
}
system("pause");
system("cls");
}
修改职工
void WorkManager::Mod_Emp()
{
if(this->m_FileIsEmpty)
{
cout<<"文件不存在或记录为空!"<<endl;
}
else
{
cout<<"请输入想要修改职工编号:"<<endl;
int id=0;
cin>>id;
int ret=this->IsExist(id);
if(ret!=-1)
{
int newId=0;
string newName;
int dSelect=0;
cout<<"查找到"<<this->m_empArray[ret]->m_id<<"号职工,请输入新职工号"<<endl;
delete this->m_empArray[ret];
cin>>newId;
cout<<"请输入新姓名"<<endl;
cin>>newName;
cout<<"请选择职工新岗位"<<endl;
cout<<"1.普通职工"<<endl;
cout<<"2.经理"<<endl;
cout<<"3.老板"<<endl;
cin>>dSelect;
worker* wk;
switch(dSelect)
{
case 1:
wk=new employee(newId,newName,dSelect);
break;
case 2:
wk=new manager(newId,newName,dSelect);
break;
case 3:
wk=new boss(newId,newName,dSelect);
break;
default:
break;
}
this->m_empArray[ret]=wk;
cout<<"修改成功"<<endl;
this->save();
}
else
{
cout<<"修改失败,未找到该职工"<<endl;
}
}
system("pause");
system("cls");
}
查找职工
void WorkManager::Find_Emp()
{
if(this->m_FileIsEmpty)
{
cout<<"文件不存在或记录为空!"<<endl;
}
else
{
cout<<"请输入查找方式:"<<endl;
cout<<"1.按照职工编号查找"<<endl;
cout<<"2.按照职工姓名查找"<<endl;
int select=0;
cin>>select;
if(select==1)
{
//按照职工编号查找
cout<<"请输入查找职工编号:"<<endl;
int id=0;
cin>>id;
int ret=this->IsExist(id);
if(ret!=-1)
{
cout<<"查找成功!该职工信息如下:"<<endl;
this->m_empArray[ret]->showInfo();
}
else
{
cout<<"查找失败!"<<endl;
}
}
else if(select==2)
{
//按照职工姓名查找
cout<<"请输入查找职工姓名:"<<endl;
string name;
cin>>name;
bool flag=false;
for(int i=0;i<this->m_EmpNum;i++)
{
if(this->m_empArray[i]->m_name==name)
{
cout<<"查找成功,职工编号为"
<<this->m_empArray[i]->m_id<<"该职工信息如下:"<<endl;
this->m_empArray[i]->showInfo();
flag=true;
}
}
if(flag==false)
{
cout<<"查找失败、查无此人!"<<endl;
}
}
else
{
cout<<"输入有误"<<endl;
}
}
system("pause");
system("cls");
}
按照编号排序
void WorkManager::Find_Emp()
{
if(this->m_FileIsEmpty)
{
cout<<"文件不存在或记录为空!"<<endl;
}
else
{
cout<<"请输入查找方式:"<<endl;
cout<<"1.按照职工编号查找"<<endl;
cout<<"2.按照职工姓名查找"<<endl;
int select=0;
cin>>select;
if(select==1)
{
//按照职工编号查找
cout<<"请输入查找职工编号:"<<endl;
int id=0;
cin>>id;
int ret=this->IsExist(id);
if(ret!=-1)
{
cout<<"查找成功!该职工信息如下:"<<endl;
this->m_empArray[ret]->showInfo();
}
else
{
cout<<"查找失败!"<<endl;
}
}
else if(select==2)
{
//按照职工姓名查找
cout<<"请输入查找职工姓名:"<<endl;
string name;
cin>>name;
bool flag=false;
for(int i=0;i<this->m_EmpNum;i++)
{
if(this->m_empArray[i]->m_name==name)
{
cout<<"查找成功,职工编号为"
<<this->m_empArray[i]->m_id<<"该职工信息如下:"<<endl;
this->m_empArray[i]->showInfo();
flag=true;
}
}
if(flag==false)
{
cout<<"查找失败、查无此人!"<<endl;
}
}
else
{
cout<<"输入有误"<<endl;
}
}
system("pause");
system("cls");
}
清空文件
void WorkManager::Clear_File()
{
cout<<"确定清空?"<<endl;
cout<<"1.确定"<<endl;
cout<<"2.返回"<<endl;
int select=0;
cin>>select;
if(select==1)
{
ofstream ofs(FILENAME,ios::trunc);
ofs.close();
if(this->m_empArray!=NULL)
{
for(int i=0;i<this->m_EmpNum;i++)
{
if(this->m_empArray[i]!=NULL)
{
delete this->m_empArray[i];
this->m_empArray[i]=NULL;
}
}
delete[] this->m_empArray;
this->m_empArray=NULL;
}
this->m_EmpNum=0;
this->m_FileIsEmpty=true;
cout<<"清空成功!"<<endl;
}
else if(select==2)
{
}
else
{
cout<<"输入有误"<<endl;
}
system("pause");
system("cls");
}
代码汇总
main.c
#include <iostream>
#include <stdlib.h>
#include "WorkManager.h"
#include "worker.h"
#include "employee.h"
#include "boss.h"
#include "manager.h"
using namespace std;
int main()
{
/*worker *w=NULL;
w=new boss(1,"zhang",1);
w->showInfo();
cout << "Hello world!" << endl;*/
WorkManager wm;
int choice=0;
while(true)
{
wm.Show_Menu();
cout << "请输入您的选择!" << endl;
cin>>choice;
switch(choice)
{
case 0://0.退出管理程序
wm.Exitsystem();
break;
case 1://增加职工信息
wm.Add_Emp();
break;
case 2://显示职工信息
wm.Show_Emp();
break;
case 3://删除离职职工
wm.delEmp();
break;
case 4://修改职工信息
wm.Mod_Emp();
break;
case 5://查找职工信息
wm.Find_Emp();
break;
case 6://按照编号排序
wm.Sort_Emp();
break;
case 7://清空所有文档
wm.Clear_File();
break;
default:
system("cls");
break;
}
}
system("pause");
return 0;
}
WorkerManager.h
#ifndef WORKMANAGER_H
#define WORKMANAGER_H
#include <stdlib.h>
#include <iostream>
#include <fstream>
#include "worker.h"
#include "employee.h"
#include "boss.h"
#include "manager.h"
#define FILENAME "empfile.txt"
using namespace std;
class WorkManager
{
public:
WorkManager();
virtual ~WorkManager();
void Show_Menu();
void Exitsystem();
//清空文件
void Clear_File();
//排序
void Sort_Emp();
//查找员工
void Find_Emp();
//修改职工
void Mod_Emp();
//职工是否存在
int IsExist(int id);
//删除职工
void delEmp();
//显示职工
void Show_Emp();
//add
void Add_Emp();
//文件保存
void save();
//初始化员工
void init_Emp();
//统计人数
int get_EmpNum();
//记录职工人数
int m_EmpNum;
//职工数组指针
worker** m_empArray;
//文件空标志
bool m_FileIsEmpty;
protected:
private:
};
#endif // WORKMANAGER_H
WorkerManager.cpp
#include "WorkManager.h"
WorkManager::WorkManager()
{
//ctor
ifstream ifs;
ifs.open(FILENAME,ios::in);
if(!ifs.is_open())
{
cout<<"文件不存在"<<endl;
this->m_EmpNum=0;
this->m_empArray=NULL;
this->m_FileIsEmpty=true;
ifs.close();
return;
}
//空文件
char ch;
ifs>>ch;
if(ifs.eof())
{
cout<<"文件为空"<<endl;
this->m_EmpNum=0;
this->m_empArray=NULL;
this->m_FileIsEmpty=true;
ifs.close();
return;
}
//有数据
int num=get_EmpNum();
cout<<"职工人数为:"<<num<<endl;
this->m_EmpNum=num;
this->m_empArray=new worker* [this->m_EmpNum];
this->init_Emp();
this->m_FileIsEmpty=false;
/*for(int i=0;i<this->m_EmpNum;i++)
{
cout<<this->m_empArray[i]->m_id<<" "
<<this->m_empArray[i]->m_name<<" "
<<this->m_empArray[i]->m_Deptid<<endl;
}*/
}
WorkManager::~WorkManager()
{
//dtor
if(this->m_empArray!=NULL)
{
for(int i=0;i<this->m_EmpNum;i++)
{
if(this->m_empArray[i]!=NULL)
{
delete this->m_empArray[i];
}
}
delete[] this->m_empArray;
this->m_empArray=NULL;
}
}
void WorkManager::Show_Menu()
{
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 WorkManager::Exitsystem()
{
cout<<"欢迎下次使用"<<endl;
system("pause");
system("cls");
exit(0);
}
void WorkManager::Add_Emp()
{
cout<<"请输入添加职工数量"<<endl;
int addnum=0;
cin>>addnum;
if(addnum>0)
{
int newSize=this->m_EmpNum+addnum; //原来加新加的人
worker** newSpace =new worker*[newSize];
//将原来拷贝到新的
if(this->m_empArray!=NULL)
{
for(int i=0;i<this->m_EmpNum;i++)
{
newSpace[i]=this->m_empArray[i];
}
}
//批量添加职工
for(int i=0;i<addnum;i++)
{
int id;
string name;
int dselect;
cout<<"请输入第"<<i+1<<"个新职工编号"<<endl;
cin>>id;
cout<<"请输入第"<<i+1<<"个新职工姓名"<<endl;
cin>>name;
cout<<"请选择职工岗位"<<endl;
cout<<"1.普通职工"<<endl;
cout<<"2.经理"<<endl;
cout<<"3.老板"<<endl;
cin>>dselect;
worker * wk=NULL;
switch(dselect)
{
case 1:
wk=new employee(id,name,1);
break;
case 2:
wk=new manager(id,name,2);
break;
case 3:
wk=new boss(id,name,3);
break;
default:
break;
}
//保存到数组中
newSpace[i+this->m_EmpNum]=wk;
}
//释放原来控件
delete [] this->m_empArray;
//更改新空间指向
this->m_empArray=newSpace;
//更新新的职工人数
this->m_EmpNum=newSize;
cout<<"成功添加"<<addnum<<"名新职工"<<endl;
this->save();
this->m_FileIsEmpty=false;
}
else
{
cout<<"输入有误"<<endl;
}
system("pause");
system("cls");
}
void WorkManager::save()
{
ofstream ofs;
ofs.open(FILENAME,ios::out);//write
for(int i=0;i<this->m_EmpNum;i++)
{
ofs<<this->m_empArray[i]->m_id<<" "
<<this->m_empArray[i]->m_name<<" "
<<this->m_empArray[i]->m_Deptid<<endl;
}
ofs.close();
}
int WorkManager::get_EmpNum()
{
ifstream ifs;
ifs.open(FILENAME,ios::in);
int id;
string name;
int did;
int num=0;
while(ifs>>id&&ifs>>name&&ifs>>did)
{
num++;
}
ifs.close();
return num;
}
void WorkManager::init_Emp()
{
ifstream ifs;
ifs.open(FILENAME,ios::in);
int id;
string name;
int did;
int index=0;
while(ifs>>id&&ifs>>name&&ifs>>did)
{
worker* wk=NULL;
if(did==1)
{
wk=new employee(id,name,did);
}
else if(did==2)
{
wk=new manager(id,name,did);
}
else if(did==3)
{
wk=new boss(id,name,did);
}
this->m_empArray[index]=wk;
index++;
}
ifs.close();
}
void WorkManager::Show_Emp()
{
if(this->m_FileIsEmpty)
{
cout<<"文件不存在或记录为空!"<<endl;
}
else
{
for(int i=0;i<m_EmpNum;i++)
{
this->m_empArray[i]->showInfo();
}
}
system("pause");
system("cls");
}
//职工是否存在
int WorkManager::IsExist(int id)
{
int index=-1;
for(int i=0;i<this->m_EmpNum;i++)
{
if(this->m_empArray[i]->m_id==id)
{
index=i;
break;
}
}
return index;
}
//删除职工
void WorkManager::delEmp()
{
if(this->m_FileIsEmpty)
{
cout<<"文件不存在或记录为空!"<<endl;
}
else
{
cout<<"请输入想要删除职工编号:"<<endl;
int id=0;
cin>>id;
int index=this->IsExist(id);
if(index!=-1)
{
for(int i=index;i<m_EmpNum-1;i++)
{
this->m_empArray[i]=this->m_empArray[i+1];
}
this->m_EmpNum--;
this->save();
cout<<"删除成功"<<endl;
}
else
{
cout<<"删除失败,未找到该职工"<<endl;
}
}
system("pause");
system("cls");
}
//修改职工
void WorkManager::Mod_Emp()
{
if(this->m_FileIsEmpty)
{
cout<<"文件不存在或记录为空!"<<endl;
}
else
{
cout<<"请输入想要修改职工编号:"<<endl;
int id=0;
cin>>id;
int ret=this->IsExist(id);
if(ret!=-1)
{
int newId=0;
string newName;
int dSelect=0;
cout<<"查找到"<<this->m_empArray[ret]->m_id<<"号职工,请输入新职工号"<<endl;
delete this->m_empArray[ret];
cin>>newId;
cout<<"请输入新姓名"<<endl;
cin>>newName;
cout<<"请选择职工新岗位"<<endl;
cout<<"1.普通职工"<<endl;
cout<<"2.经理"<<endl;
cout<<"3.老板"<<endl;
cin>>dSelect;
worker* wk;
switch(dSelect)
{
case 1:
wk=new employee(newId,newName,dSelect);
break;
case 2:
wk=new manager(newId,newName,dSelect);
break;
case 3:
wk=new boss(newId,newName,dSelect);
break;
default:
break;
}
this->m_empArray[ret]=wk;
cout<<"修改成功"<<endl;
this->save();
}
else
{
cout<<"修改失败,未找到该职工"<<endl;
}
}
system("pause");
system("cls");
}
void WorkManager::Find_Emp()
{
if(this->m_FileIsEmpty)
{
cout<<"文件不存在或记录为空!"<<endl;
}
else
{
cout<<"请输入查找方式:"<<endl;
cout<<"1.按照职工编号查找"<<endl;
cout<<"2.按照职工姓名查找"<<endl;
int select=0;
cin>>select;
if(select==1)
{
//按照职工编号查找
cout<<"请输入查找职工编号:"<<endl;
int id=0;
cin>>id;
int ret=this->IsExist(id);
if(ret!=-1)
{
cout<<"查找成功!该职工信息如下:"<<endl;
this->m_empArray[ret]->showInfo();
}
else
{
cout<<"查找失败!"<<endl;
}
}
else if(select==2)
{
//按照职工姓名查找
cout<<"请输入查找职工姓名:"<<endl;
string name;
cin>>name;
bool flag=false;
for(int i=0;i<this->m_EmpNum;i++)
{
if(this->m_empArray[i]->m_name==name)
{
cout<<"查找成功,职工编号为"
<<this->m_empArray[i]->m_id<<"该职工信息如下:"<<endl;
this->m_empArray[i]->showInfo();
flag=true;
}
}
if(flag==false)
{
cout<<"查找失败、查无此人!"<<endl;
}
}
else
{
cout<<"输入有误"<<endl;
}
}
system("pause");
system("cls");
}
void WorkManager::Sort_Emp()
{
if(this->m_FileIsEmpty)
{
cout<<"文件不存在或记录为空!"<<endl;
}
else
{
cout<<"请选择排序方式:"<<endl;
cout<<"1.按职工号进行升序"<<endl;
cout<<"2.按职工号进行降序"<<endl;
int select=0;
cin>>select;
for(int i=0;i<this->m_EmpNum;i++)
{
int minOrMax=i;
for(int j=i+1;j<this->m_EmpNum;j++)
{
if(select==1)
{
if(this->m_empArray[minOrMax]->m_id>this->m_empArray[j]->m_id)
{
minOrMax=j;
}
}
else
{
if(this->m_empArray[minOrMax]->m_id<this->m_empArray[j]->m_id)
{
minOrMax=j;
}
}
}
if(i!=minOrMax)
{
worker* temp=m_empArray[i];
m_empArray[i]=m_empArray[minOrMax];
m_empArray[minOrMax]=temp;
}
}
cout<<"排序成功,排序后结果为"<<endl;
this->save();
this->Show_Emp();
}
system("pause");
system("cls");
}
void WorkManager::Clear_File()
{
cout<<"确定清空?"<<endl;
cout<<"1.确定"<<endl;
cout<<"2.返回"<<endl;
int select=0;
cin>>select;
if(select==1)
{
ofstream ofs(FILENAME,ios::trunc);
ofs.close();
if(this->m_empArray!=NULL)
{
for(int i=0;i<this->m_EmpNum;i++)
{
if(this->m_empArray[i]!=NULL)
{
delete this->m_empArray[i];
this->m_empArray[i]=NULL;
}
}
delete[] this->m_empArray;
this->m_empArray=NULL;
}
this->m_EmpNum=0;
this->m_FileIsEmpty=true;
cout<<"清空成功!"<<endl;
}
else if(select==2)
{
}
else
{
cout<<"输入有误"<<endl;
}
system("pause");
system("cls");
}
Manager.h
#ifndef MANAGER_H
#define MANAGER_H
#include <iostream>
#include "worker.h"
using namespace std;
class manager:public worker
{
public:
manager(int id,string name,int did);
virtual ~manager();
//显示个人信息
virtual void showInfo();
//获取岗位名称
virtual string getDeptName();
protected:
private:
};
#endif // MANAGER_H
Manager.cpp
#include "manager.h"
manager::manager(int id,string name,int did)
{
//ctor
this->m_id=id;
this->m_name=name;
this->m_Deptid=did;
}
manager::~manager()
{
//dtor
}
//显示个人信息
void manager::showInfo()
{
cout<<"职工编号:"<<this->m_id
<<"\t职工姓名:"<<this->m_name
<<"\t岗位:"<<this->getDeptName()
<<"\t岗位职责:完成老板交给的任务,并下发任务给员工"<<endl;
}
//获取岗位名称
string manager::getDeptName()
{
return string("经理");
}
work.h
#ifndef WORKER_H
#define WORKER_H
#include <string>
using namespace std;
class worker
{
public:
//显示个人信息
virtual ~worker(){}
virtual void showInfo()=0;
//获取岗位名称
virtual string getDeptName()=0;
int m_id;
string m_name;
int m_Deptid;
protected:
private:
};
#endif // WORKER_H
boss.h
#ifndef BOSS_H
#define BOSS_H
#include <iostream>
#include "worker.h"
using namespace std;
class boss:public worker
{
public:
boss(int id,string name,int did);
virtual ~boss();
//显示个人信息
virtual void showInfo();
//获取岗位名称
virtual string getDeptName();
protected:
private:
};
#endif // BOSS_H
boss.cpp
#include "boss.h"
boss::boss(int id,string name,int did)
{
//ctor
this->m_id=id;
this->m_name=name;
this->m_Deptid=did;
}
boss::~boss()
{
//dtor
}
//显示个人信息
void boss::showInfo()
{
cout<<"职工编号:"<<this->m_id
<<"\t职工姓名:"<<this->m_name
<<"\t岗位:"<<this->getDeptName()
<<"\t岗位职责:管理公司所有事务"<<endl;
}
//获取岗位名称
string boss::getDeptName()
{
return string("总裁");
}
employee.h
#ifndef EMPLOYEE_H
#define EMPLOYEE_H
#include "worker.h"
#include <string>
#include <iostream>
using namespace std;
class employee:public worker
{
public:
employee(int id,string name,int did);
virtual ~employee();
//显示个人信息
virtual void showInfo();
//获取岗位名称
virtual string getDeptName();
protected:
private:
};
#endif // EMPLOYEE_H
employee.cpp
#include "employee.h"
employee::employee(int id,string name,int did)
{
this->m_id=id;
this->m_name=name;
this->m_Deptid=did;
}
employee::~employee()
{
//dtor
}
//显示个人信息
void employee::showInfo()
{
cout<<"职工编号:"<<this->m_id
<<"\t职工姓名:"<<this->m_name
<<"\t岗位:"<<this->getDeptName()
<<"\t岗位职责:完成经理交给的任务"<<endl;
}
//获取岗位名称
string employee::getDeptName()
{
return string("员工");
}