【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本质上都是类模板库。

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

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

版权声明:本博客所有文章均为原创,欢迎交流,欢迎转载;转载请勿篡改内容,并且注明出处,谢谢!

时间: 2024-10-14 19:18:27

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

C++--模板的概念和意义、深入理解函数模板、类模板的概念和意义

一.模板的概念与意义 Q:C++中有几种交换变量的方法?定义宏代码与定义函数A.定义宏代码优点:代码复用,适合所有的类型缺点:编译器不知道宏的存在,缺少类型检查B.定义函数优点:真正的函数调用,编译器对类型进行检查缺点:根据类型重复定义函数,无法代码复用 C.泛型编程--不考虑具体数据类型的编程方式Swap泛型写法中的T不是一个具体的数据类型,而是泛指任意的数据类型C++中的泛型编程函数模板--一种特殊的函数可用不同类型进行调用,看起来和普通函数很相似,区别是类型可被参数化函数模板的语法规则1.

在Linux中创建静态库.a和动态库.so

转自:http://www.cnblogs.com/laojie4321/archive/2012/03/28/2421056.html 在Linux中创建静态库.a和动态库.so 我们通常把一些公用函数制作成函数库,供其它程序使用. 函数库分为静态库和动态库两种. 1. 静态函数库 这类库的名字一般是libxxx.a:利用静态函数库编译成的文件比较大,因为整个 函数库的所有数据都会被整合进目标代码中,他的优点就显而易见了,即编译后的执行程序不需要外部的函数库支持,因为所有使用的函数都已经被编译

【C/C++学院】0825-类模板/final_override/类模板与普通类的派生类模板虚函数抽象模板类/类模板友元/位运算算法以及类声明/Rtti 实时类型检测/高级new创建/类以及函数包装器

类模板 类模板多个类型默认类型简单数组模板 #pragma once template <class T=int>//类模板可以有一个默认的值 class myArray { public: myArray(); ~myArray(); }; #include "myArray.h" template <class T=int>//每一个函数都需要加上一个默认的值 myArray<T>::myArray() //类模板成员函数在外部,需要加载类型初始

C++ 虚函数、静态联编和动态联编、抽象类

 //C++ 虚函数.静态联编和动态联编.抽象类 #include<iostream> #include<string> using namespace std; class People { private: string name; int age; public: People(string name_, int age_):name(name_), age(age_){} People(){cout << "基类默认构造函数" <&

静态联编,动态联编,类指针之间的关系,虚函数与多态性,纯虚函数,虚析构函数

1.静态联编,是程序的匹配,连接在编译阶段实现,也称为早期匹配.重载函数使用静态联编. 2.动态联编是指程序联编推迟到运行时进行,所以又称为晚期联编.switch语句和if语句是动态联编的例子. #include<iostream> void go(int num) { } void go(char *str) { } //class //::在一个类中 class A { public: void go(int num) { } void go(char *str) { } }; void

C++中的抽象类及纯虚函数的实现与否

1.含有纯虚函数的叫抽象类 2.抽象类(一般是基类)中的纯虚函数无论函数体实现与否,都没有关系,系统会自动忽略 3.继承自抽象类的子类,必须要实现父类的纯虚函数才可以实例化对象 4.抽象类不允许实例化对象,只能作为一个基类或虚接口使用 5.抽象类的指针可以指向不同的派生类对象(虚函数的功能) class Father{ public: virtual void fun() = 0{ int a = 10; };//抽象类中的纯虚函数,函数体实现了也相当于没实现,自动忽略 }; Father f;

【转】C++多态篇1一静态联编,动态联编、虚函数与虚函数表vtable

首先,说起多态就必须要讲静态联编,动态联编.这俩也叫静态绑定和动态绑定.有些书比如C++ Primer也叫静态类型和动态类型.谭浩强写的C++程序设计直接叫静态多态性和动态多态性. 文章转载自:原文链接

C/C++ 跨平台交叉编译、静态库/动态库编译、MinGW、Cygwin、CodeBlocks使用原理及链接参数选项

目录 0. 引言 1. 交叉编译 2. Cygwin简介 3. 静态库编译及使用 4. 动态库编译及使用 5. MinGW简介 6. CodeBlocks简介 0. 引言 UNIX是一个注册商标,是要满足一大堆条件并且支付可观费用才能够被授权使用的一个操作系统.linux是unix的克隆版本,是由其创始人Linus和诸多世界知名的黑客手工打造的一个操作系统.为什么linux和unix之间有很多软件可以很轻松的移植?因为linux也满足POSIX规范,所以在运行机制上跟unix相近.同时,POSI

【C/C++学院】(11)泛型编程/函数模板/类模板

1.泛型编程基础 #include "iostream" using namespace std; void swap(int &a, int &b) { int c; c = a; a = b; b = c; } void swap(float &a, float &b) { float c; c = a; a = b; b = c; } void main() { int a = 1, b = 2; swap(a, b); float a1 = 1,