您的位置:首页 > 编程语言 > C语言/C++

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

2015-11-02 12:09 639 查看

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

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

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

函数模板的作用:通用的函数,一个函数通吃所有参数不同的情况。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: