【C/C++学院】0823-静态联合编译与动态联合编译/父类指针子类指针释放/虚函数/纯虚函数概念以及虚析构函数/抽象类与纯虚函数以及应用/虚函数原理/虚函数分层以及异质链表/类模板的概念以及应用

静态联合编译与动态联合编译

#include <iostream>
#include <stdlib.h>

//散列
void go(int num)
{
	
}

void  go(char *str)
{

}
//class
//::在一个类中
class A
{
public:
	void go(int num)
	{

	}
	void  go(char *str)
	{

	}
};

void main()
{

	///auto p = go;编译的阶段,静态联编
	void(*p1)(char *str) = go;
	void(*p2)(int num) = go;

	go(NULL);
	go(nullptr);//编译器编译的时候决定就叫静态联编
}

void main1()
{
	int num;
	std::cin >> num;//执行的阶段
	if (num > 10)
	{
		system("calc");
	}
	else
	{
		system("notepad");
	}
	std::cin.get();
}

#include <iostream>
//父类与子类之间的重载,同名函数会覆盖
//即使参数类型不一样,不能直接调用,必须调用父类默认生成的对象来调用
class A
{
public:
	void go()
	{
		std::cout << "A---go";
	}
	void go(int num)
	{
		std::cout << "A---go"<<num;
	}
	void go(char *str)
	{
		std::cout << "A---go"<<str<<"str";
	}
	void goA(char *str)
	{
		std::cout << "A---go" << str << "str";
	}
};
class B :public A
{
public:
	//const  函数重载一般适用于常量对象,
	//非const一般适用于变量对象
	void go()
	{
		std::cout << "B---go";
	}
	void go() const  
	{
		std::cout << "B---go const";
	}
};

void main()
{

	B *p = new B;
	p->go();
	//p->go(1);

	const B *pb = new B;
	pb->go();
	
	std::cin.get();
}

void main1()
{
	B *pb = new B;
  //  pb->go(NULL);
	pb->goA("1");
	//pb->go("1");
	

	pb->A::go(NULL);
	pb->A::go("123");
	//pb->A::go(nullptr);//C++空指针不能打印

	std::cin.get();
}

父类指针子类指针释放

#pragma once
#include <iostream>

class fu
{
public:
	fu();
	~fu();
	char * strfu;
	void print();
	void fufu();
};
#include "fu.h"

fu::fu()
{
	this->strfu = "父亲";
	std::cout << "fu create" << std::endl;
}

fu::~fu()
{
	std::cout << "fu delete" << std::endl;
}

void fu::print()
{
	std::cout << this->strfu << "\n";
}

void fu::fufu()
{
	std::cout << "我是你爹" << "\n";
}
#pragma once
#include "fu.h"
class zi :
	public fu
{
public:
	zi();
	~zi();
	char *strzi;
	char ch[ 900000000];
	void print();
	void zizi();
};
#include "zi.h"

zi::zi()
{
	this->strzi = "儿子";
	std::cout << "zi create" << std::endl;
}

zi::~zi()
{
	std::cout << "zi delete" << std::endl;
}

void zi::print()
{
	std::cout << this->strzi << "\n";
}

void zi::zizi()
{
//	std::cout << this->strzi << "\n";
	std::cout << "我是你儿子" << "\n";
}
#include <iostream>

#include"fu.h"
#include "zi.h"

//dynamic适用于虚函数

//类而言,数据是私有,代码是公有的
//指针为空,指向一个类,可以直接调用方法
//涉及内部成员会崩溃,不涉及可以执行


//父类指针引用父类对象,完全正常引用
//子类指针引用子类对象,覆盖父类的同名函数
//父类指针引用子类对象,只能引用父类中的函数
//子类指针,引用父类对象,子类不涉及内部数据的函数会调用成功
//涉及到内部数据的会调用成功,执行失败
//子类指针可以引用父类的不重名的函数
//子类指针(不是pzi->fu::print();方法)无法引用父类
//的同名方法

void main()
{
	{
		//fu *pfu = new fu;
		//delete pfu;
	}
	{
	   ///  zi  *pzi = new zi;
		// delete pzi;
	}
	{
		//fu *pfu = new zi;
		//delete pfu;//内存泄漏
	}
	{
		//fu *pfu = new fu;
	    zi *pzi = static_cast<zi *>(new fu);
		delete pzi;//内存越界,超过界限释放内存,有时出错,有时无措     
	}

	std::cin.get();
}

void main3()
{
	zi *pzi(nullptr);
	pzi->zizi();

	std::cin.get();
}

void main4()
{
	fu *pfu = new fu;
	zi *pzi = static_cast<zi *>(pfu);
	pzi->fufu();
	
	pzi->zizi();
	pzi->fu::print();

	//pzi->print();

	//std::cout << pzi->strzi << std::endl;	

	//pzi->print();

	std::cin.get();
}

void main2()
{
	fu *pfu = new zi;
	pfu->print();
	pfu->fufu();
	
	std::cin.get();
}

void main1()
{
	fu *pfu = new fu;
	pfu->print();
	pfu->fufu();

	zi *pzi = new zi;
	pzi->print();//子类覆盖父类
	pzi->zizi();
	pzi->fufu();

	/*
	fu fu1;
	fu1.print();
	fu1.fufu();
	*/

	std::cin.get();
}

虚函数

#include<iostream>

//没有virtual,会一直调用基类的方法
//virtual的

//虚函数现代编译器会直接分配一个指针存储虚函数表的位置,

class fu
{
public:
	virtual   void name() 
	{
		std::cout << "父类";
		std::cout << "x=" << x << "\n";
	}
	int x;
	fu(int a) :x(a)
	{

	}
protected:
private:
};

class zi :public fu
{
public:
	void name()
	{
		std::cout << "子类";
		std::cout << "x=" << x << ",y="<<y<<"\n";
	}
	int y;
	zi(int a, int b) :fu(a), y(b)
	{

	}
protected:
private:
};

class sun :public zi
{
public:
	void name()
	{
		std::cout << "孙类";
		std::cout << "x=" << x << ",y=" << y <<",z="<<z<< "\n";
	}
	int z;
	sun(int a, int b, int c) :zi(a, b), z(c)
	{

	}
protected:
private:
};


void main()
{

	std::cout << sizeof(fu) << std::endl;
	fu fu1(1);
	zi zi1(2,3);
	sun sun1(4,5,6);
	fu *pfu;
	pfu = &fu1;
	pfu->name();//1

	pfu = &zi1;
	pfu->name();//2

	pfu = &sun1;
	pfu->name();//4
	
	//((zi*)pfu)->name();
	//((sun*)pfu)->name();

	std::cin.get();
}

void main1()
{
	/*
	fu *pfu = new fu;
	pfu->name();
	zi *pzi = new zi;
	pzi->name();
	sun *psun = new sun;
	psun->name();

	zi *pzifu = static_cast<zi *>(pfu);
	pzifu->name();

	sun *psunfu = static_cast<sun *>(pfu);
	psunfu->name();


	std::cin.get();
	*/
}
#include "mainwindow.h"
#include <QApplication>
#include<QDebug>
#include<QPushButton>

class base
{
public:
    virtual  void show()//基类,接口
    {
        qDebug()<<"show";
    }
};

class mywindow: public base
{
 public:
    MainWindow *p;
    mywindow()
    {
        p=new MainWindow;
    }
   void  show()
    {
        this->p->show();
      // return 0;
    }
};

class mybutton:  public base
{
public:
    QPushButton *p;
    mybutton()
    {
        p= new QPushButton("1234");
    }
    void show(int num)
    {
        this->p->show();
    }
};


int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    base  base1;
    mywindow  mywindow1;
    mybutton mybutton1;

    base *p=&base1;//基类

    p->show();
    p= &mywindow1;
    p->show();
    p=&mybutton1;
    p->show();

    return a.exec();
}

纯虚函数概念以及虚析构函数

#include <iostream>

using namespace std;

class A
{
public:
    A()//构造函数不可以是虚函数,不会再构造,没有办法创建子类中的父类对象
    {
       std::cout<<"a create"<<std::endl;
    }
   virtual ~A()//虚析构函数,让父类指针正确的释放子类对象的内存
    {
         std::cout<<"a delete"<<std::endl;
    }
};

class B:public A
{
public:
    B()//B 创建自动调用A的构造函数
    {
       std::cout<<"b create"<<std::endl;
    }
    ~B()//B析构的时候会自动调用A的析构函数
    {
       std::cout<<"b delete"<<std::endl;
    }
};

int main()
{
   A * p =new B;
    delete p;

   // cout << "Hello World!" << endl;
    return 0;
}

抽象类与纯虚函数以及应用

#include<iostream>

class base
{
public:
	//纯虚函数,有无定义都可以
	//有一个纯虚函数,都是抽象类,无法实例化
	virtual void  run()=0 //限定一个类不能实例化,专门的接口
	{
		std::cout << "base run\n";
	}
	virtual ~base()
	{

	}
};
//抽象类不可以用于函数的参数以及返回值类型
//抽象类指针是可以
base * test( base *p)
{
	base *pbase(nullptr);
	return pbase;
}

class boy :public base
{
public:
	void run()
	{
		std::cout << "男孩奔跑\n";
	}
};

class girl :public base
{
public:
	void run()
	{
		std::cout << "女孩奔跑\n";
	}
};

void main()
{
	//抽象类无法实例化对象,可以实话指针
	//纯虚函数与抽象类与虚函数起到接口的作用
	//用同一个接口完成不同的功能
	//纯虚函数完全就是为了接口的存在,有了纯虚函数的类无法实例化
	//虚函数占4个字节,就是指针,函数指针

	boy boy1;
	girl girl1;
	base *p(nullptr);
	p = &boy1;
	p->run();
	p = &girl1;
	p->run();

	std::cin.get();
}

纯虚函数:virtual void run()=0;等于0,限定一个类不能实例化,只是一个专门的接口

虚函数:virtual void run();

#include "dialog.h"
#include <QApplication>
#include<QPushButton>
#include<QLabel>

//抽象类也可以实现继承
class basebase
{
public:
    virtual void show()=0;
    virtual void hide()=0;
};

//接口,操作不同的类对象的方法
class base :public basebase
{
public:
  virtual void resize(int x,int y)=0;
  virtual void move (int cx,int cy)=0;
};

class myself: public base
{
public:
    //只要有一个接口的没有实现,抽象类
    //吧所有就诶口都实现了的类才可以实例化
    void show()
    {

    }
    void hide()
    {

    }
};

class mydialog: public base
{

public:
    Dialog w;
    void show()
    {
        w.show();
    }
    void hide()
    {
        w.hide();
    }

    void resize(int x,int y)
    {
        w.resize(x,y);
    }

    void move (int cx,int cy)
    {
        w.move(cx,cy);
    }
};

class mybutton: public base
{
public:
    QPushButton w;
    void show()
    {
        w.show();
    }
    void hide()
    {
        w.hide();
    }

    void resize(int x,int y)
    {
        w.resize(x,y);
    }

    void move (int cx,int cy)
    {
        w.move(cx,cy);
    }
};

class mylabel: public base
{
public:
    QLabel w;
    void show()
    {
        w.show();
    }
    void hide()
    {
        w.hide();
    }

    void resize(int x,int y)
    {
        w.resize(x,y);
    }

    void move (int cx,int cy)
    {
        w.move(cx,cy);
    }
};


int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    //myself  my1;

    return a.exec();
}


int main1(int argc, char *argv[])
{
    QApplication a(argc, argv);
   // Dialog w;
   // w.show();
    mydialog  dialog1;
    mybutton  button1;
    mylabel   label1;
    base *pbase(nullptr);
    pbase =&dialog1;
    pbase->show();
    pbase->resize(100,200);
    pbase =&button1;
    pbase->show();
     pbase->resize(200,200);
    pbase=&label1;
    pbase->show();
    pbase->resize(300,200);

    return a.exec();
}

虚函数原理

cl /d1 reportSingleClassLayoutxxx yyy.cpp 

进行编译,可以查看虚函数表

#include <iostream>

using namespace std;

//仅有一个指针指向虚函数表

//1个或者多个虚函数,或者多个纯虚函数都占四个字节
//一个指针存储了虚函数表的地址
class basebase
{
public:
    virtual void show()=0;
    virtual void hide()=0;
    virtual void run()=0;
};

class base
{
public:
    virtual void show()
    {

    }
    virtual void hide()
    {

    }
    virtual void run()
    {

    }
};

class china
{
    int  num;
};


int main()
{
    cout<<sizeof(basebase)<<endl;
    cout<<sizeof(base)<<endl;

    return 0;
}

虚函数分层以及异链表

程序中,用基类类型指针,可以生成一个连接不同派生类对象的动态链表,即每个节点节点指针可以指向类层次中不同的派生类对象。这种节点类型不相同的链表称为异质链表。

#include "mainwindow.h"
#include <QApplication>
#include<QPushButton>
#include<QLabel>

class base
{
public:
    virtual  void  show()=0;
};

class node
{
 public:
      base *p;       //数据域
      node *pNext;//指针域
};

void showall(node *phead)
{
    while(phead!=NULL)
    {

       phead->p->show();
       phead= phead->pNext;
    }
}

node * add(node *phead, base *p)//改变一个指针需要二级指针,否则需要返回值并赋值
{
    if(phead==NULL)
    {
        //phead=p;
        node *px= new node;//开辟节点
        px->pNext=NULL;//最后一个节点为空
        px->p=p;//存储传过来的指针

        phead =px;//连接

        return phead;
    }
    else
    {
        node *pbak=phead;//保存头结点地址
        while(phead->pNext!=NULL)//遍历到最后一个节点
        {
           phead=phead->pNext;
        }
        node *px= new node;//开辟就诶点
        px->pNext=NULL;//最后一个节点为空
        px->p=p;//存储传过来的指针

        phead->pNext=px;//连接这个就诶点

        return pbak;
    }
}

class button:public base
{
public:
    QPushButton w;
    void show()
    {
        w.show();
    }
};

class window:public base
{
public:
    MainWindow  w;
    void show()
    {
        w.show();
    }
};

class  label:public base
{
public:
    QLabel  w;
    void show()
    {
        w.show();
    }
};


int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    node *phead=NULL;//指针必须初四化
    button b1,b2,b3;
    window w1,w2,w3;
    label l1,l2,l3;

    phead=add(phead,&b1);
    phead=add(phead,&w1);
    phead=add(phead,&l1);

    showall(phead);

    return a.exec();
}

int main2(int argc, char *argv[])
{
    QApplication a(argc, argv);
    node *phead;
    button b1,b2,b3;
    window w1,w2,w3;
    label l1,l2,l3;

    node node1,node2,node3,node4;
    phead=&node1;
    node1.pNext=&node2;
    node2.pNext=&node3;
    node3.pNext=&node4;
    node4.pNext=NULL;//串联起来
    node1.p=&b1;
    node2.p=&w1;
    node3.p=&l1;
    node4.p=&b2;

    showall(phead);

    return a.exec();
}

类模板的概念以及应用

#include<iostream>

int add(int a, int b)
{
	std::cout << "add int\n";
	return a + b;
}

double  add(double a, double b)
{
	std::cout << "add double\n";
	return a + b;
}

template <class T>
T  add(T a, T b)
{
	std::cout << "add T\n";
	return a + b;
}

class  com1
{
public:
	int a;
	int b;
	int  add()
	{
		return a + b;
	}
};

class  com2
{
public:
	double a;
	double b;
	double  add()
	{
		return a + b;
	}
};

template  <class T>
class  com
{
public:
	T a;
	T b;
	T add()
	{
		std::cout << typeid(T).name() << std::endl;
		return a + b;
	}
};

void main()
{
	com<double> comx;
	comx.a = 19;
	comx.b = 29.8;
	std::cout << comx.add();

	std::cin.get();
}

void main2()
{
	com2 com21;
	com21.a = 10;
	com21.b = 20.9;
	std::cout<<com21.add()<<std::endl;

	std::cin.get();
}

void main1()
{
	//add<int>(1, 2);
	//std::cout<<add<int>(2.0, 3.4)<<std::endl;

	std::cin.get();
}
#include "mainwindow.h"
#include <QApplication>
#include<QPushButton>
#include<QLabel>

template<class T>
class run
{
   public:
    T w;
    void show()
    {
        w.show();
    }
    void settext()
    {
        w.setText("A");
    }
};


int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    run<QPushButton> run1;
    run1.show();
    run1.settext();

    return a.exec();
}

std::vetcor<int> myx;//STL, boost本质上都是类模板库

类模块的作用:通用的类,不同的数据类型,相同的操作,使用的时候,只需要指明类型就可以了。通过不同的类型就给出该模板的实例化。

函数模板的作用:通用的函数,一个函数通吃所有参数不同的情况。


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值