静态联合编译与动态联合编译
#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