yangyuqing

多态原理探究

理论知识:

  • 当类中声明虚函数时,编译器会在类中生成一个虚函数表
  • 虚函数表是一个存储类成员函数指针的数据结构
  • 虚函数表是由编译器自动生成与维护的
  • virtual成员函数会被编译器放入虚函数表中
  • 当存在虚函数时,每个对象中都有一个指向虚函数表的指针(C++编译器给父类对象、子类对象提前布局vptr指针;当进行howToPrint(Parent *base)函数是,C++编译器不需要区分子类对象或者父类对象,只需要再base指针中,找vptr指针即可。)
  • VPTR一般作为类对象的第一个成员 

 

证明vptr指针存在

#include <iostream>
using namespace std;


class Parent1
{
public:
    Parent1(int a=0)
    {
        this->a = a;
    }

    void print() 
    {
        cout<<"我是父类"<<endl;
    }
private:
    int a;
};

class Parent2
{
public:
    Parent2(int a=0)
    {
        this->a = a;
    }

    virtual void print()  
    {
        cout<<"我是父类"<<endl;
    }
private:
    int a;
};

void main()
{
    printf("sizeof(Parent):%d sizeof(Parent2):%d \n", sizeof(Parent1), sizeof(Parent2));
    cout<<"hello..."<<endl;
    system("pause");
    return ;
}

 

 输出结果

 

 

构造函数中调用虚函数能发生多态吗?

#include <iostream>
using namespace std;

//构造函数中调用虚函数能发生多态吗?

class Parent
{
public:
    Parent(int a=0)
    {
        this->a = a;
        print();//在父类中执行虚函数
    }

    virtual void print()  
    {
        cout<<"我是父类"<<endl;
    }

private:
    int a;
};

class Child : public Parent
{
public:
    Child(int a = 0, int b=0):Parent(a)
    {
        this->b = b;
        print();//在子类中执行虚函数
    }

    virtual void print()
    {
        cout<<"我是子类"<<endl;
    }
private:
    int b;
};

void HowToPlay(Parent *base)
{
    base->print(); //有多态发生  //2 动手脚  

}

void main()
{

    Child  c1; //定义一个子类对象 ,在这个过程中,在父类构造函数中调用虚函数print 能发生多态吗?
    //c1.print();

    cout<<"hello..."<<endl;
    system("pause");
    return ;
}

 

 

 

 

 

父类指针和子类指针的步长

1) 铁律1:指针也只一种数据类型,C++类对象的指针p++/--,仍然可用。

2) 指针运算是按照指针所指的类型进行的。

  p++《=》p=p+1 //p = (unsigned int)basep + sizeof(*p) 步长。

3) 结论:父类p++与子类p++步长不同;不要混搭,不要用父类指针++方式操作数组。

 

 

纯虚函数和抽象类

 

 

#include<iostream>
using namespace std;

//面向抽象类编程(面向一套预先定义好的接口编程)
//解耦合 ....模块的划分


class Figure//抽象类
{
public:
    //约定一个统一的界面(接口)让子类使用 让子类必须去实现
    virtual void getArea()=0;//纯虚函数
protected:
private:
};


//圆形
class Circle:public Figure
{
public:
    Circle(int a,int b)
    {
        this->a;
        this->b;
    }
    virtual void getArea()
    {
        cout<<"圆形的面积:"<<3.14*a*a<<endl;
    }
private:
    int a;
    int b;
};

//三角形
class Tri:public Figure
{
public:
    Tri(int a,int b)
    {
        this->a;
        this->b;
    }
    virtual void getArea()
    {
        cout<<"三角形的面积:"<<a*b/2<<endl;
    }
private:
    int a;
    int b;
};

//四边形
class Square:public Figure
{
public:
    Square(int a,int b)
    {
        this->a;
        this->b;
    }
    virtual void getArea()
    {
        cout<<"四边形的面积:"<<a*b<<endl;
    }
private:
    int a;
    int b;
};

void objplay(Figure *base)
{
    base->getArea();//会发生多态
}


void main()
{
    //Figuer f;//抽象类不能被实例化
    Figure *base=NULL;

    Circle c1(10,20);
    Tri t1(20,30);
    Square s1(50,60);
    

    
    objplay(&c1);
    objplay(&t1);
    objplay(&s1);

    system("pause");
}

 

 

 

编写一个C++程序, 计算程序员( programmer )工资  

1 要求能计算出初级程序员( junior_programmer ) 中级程序员 ( mid_programmer )高级程序员( adv_programmer)的工资

2 要求利用抽象类统一界面,方便程序的扩展, 比如:新增, 计算 架构师 (architect ) 的工资

 

#include<iostream>
using namespace std;

/*
编写一个C++程序, 计算程序员( programmer )工资  
    1 要求能计算出初级程序员( junior_programmer ) 中级程序员 ( mid_programmer )高级程序员( adv_programmer)的工资
    2 要求利用抽象类统一界面,方便程序的扩展, 比如:新增, 计算 架构师 (architect ) 的工资
*/
class programmer
{
public:
    virtual void getSal()=0;
private:
};

//初级程序员( junior_programmer )
class junior_programmer:public programmer
{
public:
    junior_programmer(char *name,char *job,int sal)
    {
        this->name=name;
        this->job=job;
        this->sal=sal;
    }
    virtual void getSal()
    {
        cout<<name<<" "<<job<<" : "<<sal<<endl;
    }
protected:
private:
    char *name;
    char *job;
    int sal;
};


//中级程序员 ( mid_programmer )
class mid_programmer:public programmer
{
public:
    mid_programmer(char *name,char *job,int sal)
    {
        this->name=name;
        this->job=job;
        this->sal=sal;
    }
    virtual void getSal()
    {
        cout<<name<<" "<<job<<" : "<<sal<<endl;
    }
protected:
private:
    char *name;
    char *job;
    int sal;
};


//高级程序员( adv_programmer)
class adv_programmer:public programmer
{
public:
    adv_programmer(char *name,char *job,int sal)
    {
        this->name=name;
        this->job=job;
        this->sal=sal;
    }
    virtual void getSal()
    {
        cout<<name<<" "<<job<<" : "<<sal<<endl;
    }
protected:
private:
    char *name;
    char *job;
    int sal;
};


//架构师
class architect:public programmer
{
public:
    architect(char *name,char *job,int sal)
    {
        this->name=name;
        this->job=job;
        this->sal=sal;
    }
    virtual void getSal()
    {
        cout<<name<<" "<<job<<" : "<<sal<<endl;
    }
protected:
private:
    char *name;
    char *job;
    int sal;
};


//计算函数 简单的框架
void CalProgSal(programmer *base)
{
    base->getSal();
}


void main()
{
    junior_programmer jp("小王","初级",4000);
    mid_programmer mp("小张","中级",8600);
    adv_programmer ap("小李","高级",15000);

    //系统扩展
    architect ar("小高","架构师",24000);

    CalProgSal(&jp);
    CalProgSal(&mp);
    CalProgSal(&ap);
    CalProgSal(&ar);
    system("pause");
}

 

 

 

 

 

案例:socketc++模型设计和实现

企业信息系统框架集成第三方产品

案例背景:一般的企业信息系统都有成熟的框架。软件框架一般不发生变化,能自由的集成第三方厂商的产品。

案例需求:请你在企业信息系统框架中集成第三方厂商的Socket通信产品和第三方厂商加密产品。

        第三方厂商的Socket通信产品:完成两点之间的通信;

        第三方厂商加密产品:完成数据发送时加密;数据解密时解密。

 

 

案例要求

     1)能支持多个厂商的Socket通信产品入围

    2)能支持多个第三方厂商加密产品的入围

    3)企业信息系统框架不轻易发生框架

 

需求实现

    思考1:企业信息系统框架、第三方产品如何分层

    思考2:企业信息系统框架,如何自由集成第三方产品

      (软件设计:模块要求松、接口要求紧)

    思考3:软件分成以后,开发企业信息系统框架的程序员,应该做什么?

    第三方产品入围应该做什么?

 

编码实现

      分析有多少个类 CSocketProtocol  CSckFactoryImp1 CSckFactoryImp2

      CEncDesProtocol  HwEncdes  ciscoEncdes

      1、 定义 CSocketProtocol  抽象类

      2、 编写框架函数

      3、 编写框架测试函数

      4、 厂商1(CSckFactoryImp1)实现CSocketProtocol、厂商2(CSckFactoryImp1)实现CSocketProtocol

      5、 抽象加密接口(CEncDesProtocol)、加密厂商1(CHwImp)、加密厂商2(CCiscoImp)),集成实现业务模型

      6、 框架(c语言函数方式,框架函数;c++类方式,框架类)

 

几个重要的面向对象思想

      继承-组合(强弱)

      注入

      控制反转 IOC

      MVC

      面向对象思想扩展aop思想

      aop思想是对继承编程思想的有力的补充

 

分类:

技术点:

相关文章:

  • 2022-12-23
  • 2021-11-10
  • 2021-04-20
  • 2021-07-28
  • 2021-12-03
  • 2021-10-18
猜你喜欢
  • 2021-06-03
  • 2021-07-30
  • 2021-06-29
  • 2022-01-03
  • 2021-07-26
相关资源
相似解决方案