黑马C++(核心)

假期没网,是时候整理一下子笔记了

内存分区模型

程序运行前

  1. 代码区
  • 共享(多次运行) 只读(防止修改)
  1. 全局区
  • 全局变量、静态变量、常量(字符常量、其他常量)
  • 该区域的数据在结束后由操作系统释放

程序运行后

  1. 栈区
  • 局部变量、形参
  • 由编译器管理开辟释放
  • 不要返回局部变量的地址
  1. 堆区
  • 由程序员分配释放,当程序员不释放时,由操作系统回收
  • 主要利用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;
}

引用

  1. 给变量起别名 int & b=a
  2. 注意事项
  • 引用必须初始化
  • 引用初始化后不能修改
  1. 引用作函数参数
  • 简化指针操作
  1. 引用做函数返回值
  • 不要返回局部变量的引用
  • 返回值是引用时可以作为左值
#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;
}

  1. 引用的本质
  • 引用本质是指针常量
  1. 常量引用
  • const int & b=10合法
  • 限定形参(避免函数对参数进行修改)

函数

  1. 函数默认参数
  • 如果某个位置有默认参数,则从该位置起从左到右必须有默认参数
#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)
{
	//二义性
}
  1. 函数占位参数
  • 调用时必须填补参数
  • 占位参数可以有默认参数
int fun(int a,int);
  1. 函数重载
  • 同一作用域
  • 函数名相同
  • 函数参数类型、个数、顺序
  • 返回值不能作为函数重载条件
#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;
}

面向对象编程

封装

  1. 封装的意义
  • 将属性和行为作为一个整体,表现生活中的事物
  • 将属性和行为加以权限控制
#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;
}

  1. 访问权限
  • public
  • protected
  • private
  1. struct class
  • struct 默认权限是public class是private
  1. 成员属性私有化
#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;
}

对象的初始化和清理

  1. 构造和析构
  • 构造函数:主要作用是创建对象时为成员属性赋值,由编译器调用,可以重载
  • 析构函数:对象销毁前系统自动调用,执行一些清理工作
Person()
{
	cout<<"构造函数调用"<<endl;
}
~Person()
{
	cout<<"析构函数调用"<<endl;
}
  1. 构造函数分类和调用
  • 无参构造(默认) 有参构造
  • 普通构造 拷贝构造
#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;
}

  1. 拷贝构造函数调用时机
  • 用已有对象创建新的对象
  • 值传递
  • 以值的方式返回局部对象
#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;
}

  1. 构造函数调用规则
  • 默认构造(空实现)、析构函数(空实现)、拷贝构造(值拷贝)
  • 如果用户有参数构造,则C++不提供默认构造,但会提供拷贝构造
  • 如果用户有拷贝构造,则C++不会提供其他构造函数
  1. 深拷贝和浅拷贝
  • 浅拷贝:简单幅值 //堆区内存重复释放
  • 深拷贝:重新申请空间,进行拷贝操作

如果有属性在堆区开辟时,一定要自己提供拷贝构造函数,防止浅拷贝带来的问题

#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;
}

  1. 初始化列表
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)
{

}
  1. 类对象作为类成员
  • 当其他类对象作为本类成员,构造时先构造类对象,再构造自身

  • 析构顺序 先析构自身,在析构内部成员

#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;
}

  1. 静态成员
  • 静态成员
    • 所有对象共享同一份数据

    • 编译阶段分配内存

    • 类内声明,类外初始化

    • 访问方式

      • 类名访问
      • 对象访问
#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;
}

  1. 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;
}

  1. 空指针调用成员函数
#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;
}

  1. 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;
}


友元

  1. 全局函数做友元
#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;
}

  1. 友元类
#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;
}

  1. 成员函数做友元

friend void good::visit()

运算符重载

加号运算符重载

Person personaddper(Person &p)
Person operator+ (Person &p)

  1. 成员函数重载
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;
}
  1. 全局函数重载
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;
}
  1. 函数重载(运算符重载)
    Person+int

左移运算符重载

  1. 场景:对象输出
  2. 不会利用成员运算符重载<<运算符 ,只能利用全局函数重载左移运算符

链式编程思想

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;
}
  1. 友元函数
  • 重载左移运算符配合友元可以实现输出自定义数据类型
#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;
}

幅值运算符重载

  1. 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;
}

函数调用运算符重载

  1. 函数调用运算符() 仿函数 没有固定的写法非常灵活
#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 都访问不到

  1. 公共继承

不变

  1. 保护继承

都变成保护

  1. 私有继承

都变成私有

继承的对象模型

  1. 父类中所有的非静态成员属性都会被子类继承下去
#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;
}

继承中构造和析构顺序

  1. 子类继承父类后,当创建子类对象,也会调用父类的构造函数

先后顺序验证

#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;
}

父类构造
子类构造
子类析构
父类析构

继承中同名成员

  1. 同名成员属性
cout<<s.m_a<<endl;
    cout<<s.Base::m_a<<endl;
  1. 同名成员函数
#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;
}

继承中同名静态成员处理

  1. 加作用域
  2. son::base::m_a; son访问 base作用域下的m_a

多继承语法

class zi:public fu,public fu2

  1. 不建议使用
class Son:public Base1,Public Base2

菱形继承

  1. 两个派生类继承同一个基类,另一个类同时继承两个派生类
  2. 问题:会产生二义性,实际只需要一份数据

//虚继承解决菱形继承问题;
//(虚基类指针)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;
}

多态

多态概念

  1. 动态多态
  • 派生类和虚函数实现运行时多态,运行阶段确定函数地址

条件:子类重写父类的虚函数 使用:使用父类引用,执行子类对象

#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;
}

  1. 多态原理剖析
//vfptr (虚函数指针)->vftable虚函数表  子类替换父类的虚函数地址
void test01()
{
    cout<<sizeof(Animal)<<endl;
    cout<<sizeof(Dog)<<endl;
    cout<<sizeof(Cat)<<endl;
}

案例-计算器类

  1. 设计实现两个操作数进行运算的计算器类

优点:代码组织结构清晰,可读性强,利于扩展维护

普通实现

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;

}

纯虚函数 和抽象类

  1. 写法 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);
}

虚析构,纯虚析构

  1. 语法
    ~p()
    ~p()=0
  2. 如果子类没有堆区数据,可以不写虚析构。有虚析构的也是抽象类
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

  1. 文件分类
  • 文本文件:ASCII
  • 二进制文件:binary
  1. 文件操作
    ofstream ifstream fstream

文本文件

  1. 写文件
  • 包含头文件
  • 创建流对象
  • 打开文件
打开方式解释
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();
}
  1. 读文件
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();
}

二进制

  1. 写文件
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();
}
  1. 读文件
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();


}

职工管理系统

  1. 职工分类:普通员工、经理、老板 需要显示职工编号、姓名、岗位、职责
  • 普通员工:完成员工交给的任务
  • 经理职责:完成老板交给的任务,并下发任务给员工
  • 老板:管理公司所有事务
  1. 功能
  • 退出管理程序
  • 增加职工信息:实现批量添加职工功能,将信息录入到文件中,职工信息为
    :职工编号、姓名、部门编号
  • 显示职工信息:显示公司内部所有职工信息
  • 删除离职职工:删除指定职工
  • 修改职工信息:按编号修改
  • 查找职工信息:按照职工编号或姓名查找
  • 按照编号排序
  • 清空所有文档:清空文件中记录的所有职工信息

创建管理类

  1. 与用户的沟通菜单界面
  2. 对职工增删改查
  3. 与文件的读写操作
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");
}

创建职工类

  1. 创建职工抽象类
#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

  1. 创建普通员工类
#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("员工");
}

  1. 创建经理类
    manager
  2. 创建老板类
    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");
}

文件交互

  1. 写文件
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();
}
  1. 读文件
  • 文件不存在
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("员工");
}

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值