首页 > 代码库 > override,final的使用,两者都是针对虚函数,也就是说要有virtual关键字

override,final的使用,两者都是针对虚函数,也就是说要有virtual关键字



1.override,final的使用,两者都是针对虚函数,也就是说要有virtual关键字

#include<iostream>

 

//C++中的finaloverride主要是针对虚函数

//加了final表示拒绝重写,这是为了使某些情况下,拒绝接口的重写

//override,声明重写父类的方法,前提是要有virtual关键字修饰函数。

//当父类没有接口,会提示错误

classye

{

public:

   //final修饰的函数必须是虚函数,通过这种方式避免重写了一些老的接口

   virtualvoidprint()final//加了final表示虚函数无法重写了

   {

       std::cout << "爷爷\n";

   }

   virtualvoidrun()

   {

       std::cout << "爷爷run\n";

   }

};

 

classba :publicye

{

public:

   voidrun()override

   {

       std::cout << "爸爸run\n";

   }

};

 

voidmain()

{

   baba1;

   ba1.run(); //结果是:爸爸run

 

   std::cin.get();

}

2.RTTI实时类类型检测

#include<iostream>

//rtti,实时类类型检测

//typeid,dynamic_cat必须依赖于虚函数表

//类型不匹配转换失败,返回为空,类型安全

 

//成员变量的覆盖

//虚函数有虚函数表确定数据类型

 

classA

{

public:

   intnum;

   staticintdata;

   virtualvoidrun()

   {

       std::cout << "A run \n";

   }

};

 

//A中的静态变量进行初始化

intA::data = 1;

classB :publicA

{

public:

   intnum = 0;

   staticintdata;

   voidrun()

   {

       std::cout << "B run\n";

   }

   voidtest()

   {

       std::cout << num <<"\n";

       std::cout << "B test\n";

   }

};

 

intB::data = 2;

 

voidmain()

{

   Aa1;

   Bb1;

   A *p1 = &a1;

   A *p2 = &b1;

   B *p3(nullptr);

   //p3 = static_cast<B *>(p1);//直接赋地址,不安全,与虚函数无关

   p3 =reinterpret_cast<B *>(p2);

   std::cout << p3 <<"\n";

   p3->test();

 

   std::cin.get();

   //此次运行结果:

   //008FFE70

   //0

   //B test

}

3.C函数指针复习

#include<stdlib.h>

 

intadd(inta,intb)

{

   returna +b;

}

 

voidrun()

{

   printf("\nrun");

}

 

voidmain()

{

   int(*p)(int,int) =add;//指向add的函数指针

   void(*p1)() = run;//指向run的函数指针

   printf("%d\n",p(1,2));

   printf("%d\n",(*p)(1,2));//*p编译器自动将*p解释为p

   printf("%d\n",(******p)(1,2));//*p编译器自动将*p解释为p

 

   printf("%d\n", (&(**p))(1, 2));//&没有*不可以执行,超过两个地址就不可以

   //&p不能,

   //printf("%d\n", (&(p))(1, 2));

   printf("%p,%p,%p", &p, *p,p);

   printf("\n%p,%p,%p", &p1, *p1,p1);

   //取地址,就是CPU即将调用函数执行

 

   getchar();

}

运行结果:

4.CPP函数指针

#include<iostream>

#include<stdlib.h>

 

voidadd(inta,intb)

{

   std::cout << a +b <<std::endl;

}

 

voidmain()

{

   void(*p)(int,int) =add;

   p(1, 2);

   (*p)(1,2);//函数指针,会被当做指针来处理,*pp效果一样

   (*************p)(1,2);//函数指针,会被当做指针来处理,*pp效果一样

   (*&p)(1,2);

   (*******&p)(1,2);

   std::cout << (void *)p << " " << (void *)(*p) <<std::endl;

   std::cout << typeid(p).name() << std::endl;

   std::cout << typeid(*p).name() << std::endl;

   std::cout << typeid(&p).name() << std::endl;

   std::cout << typeid(*&p).name() << std::endl;

   //C++编译器会自动将*p处理为p

   std::cin.get();

}

运行结果:

5.类成员函数指针数组

#include<iostream>

#include<stdio.h>

 

//类成员函数指针,类成员函数指针数组,类成员二级函数指针

classcom

{

private:

   inta;

   intb;

public:

   com(intx,inty) :a(x),b(y)

   {

   }

   int jia(inta,intb)

   {

       returna +b;

   }

   int jian(inta,intb)

   {

       returna -b;

   }

   int cheng(inta,intb)

   {

       returna *b;

   }

   int chu(inta,intb)

   {

       returna /b;

   }

};

 

voidmain()

{

   comcom1(100, 20);

   autofun1 = &com::jia;

   int(com::*p)(int,int) = &com::jia; //注意这里要加上对象名

   std::cout << (com1.*p)(10, 20) << std::endl;//引用对象,类成员函数指针

   std::cout << typeid(p).name() << std::endl;

   std::cout << typeid(fun1).name() << std::endl;

 

   std::cin.get();

}

5.CPP函数指针数组

#include<iostream>

#include<stdio.h>

 

//类成员函数指针,类成员函数指针数组,类成员二级函数指针

classcom

{

private:

   inta;

   intb;

public:

   com(intx,inty) :a(x),b(y)

   {

   }

   int jia(inta,intb)

   {

       returna +b;

   }

   int jian(inta,intb)

   {

       returna -b;

   }

   int cheng(inta,intb)

   {

       returna *b;

   }

   int chu(inta,intb)

   {

       returna /b;

   }

};

 

typedefint(com::*P)(int,int);//为函数指针定义别名p

voidmain()

{

   comcom1(100, 200);

   //下面这种方式也是没有错的

   //P fun1[4] = { &com::jia, &com::jian, &com::cheng,&com::chu };

   //类成员函数指针数组

   int(com::*fun1[4])(int,int) = { &com::jia, &com::jian, &com::cheng, &com::chu };

   for (inti = 0;i < 4;i++)

   {

       std::cout << (com1.*fun1[i])(10, 20) << std::endl;

   }

   int(com::**funp)(int,int) =fun1;//指向类成员函数指针的指针

   for (;funp <fun1 + 4;funp++)

   {

       std::cout << (com1.**funp)(10, 20) << std::endl;

       printf("%p",*funp);

   }

 

   for (inti = 0;i < 4;i++)

   {

       autofunc =fun1[i];

       std::cout << typeid(func).name() << std::endl;

       printf("%p",func);

   }

   std::cin.get();

}

运行结果:

6.高级new对象

#include<iostream>

 

classmyclass

{

public:

   myclass()

   {

       std::cout << "创建\n";

   }

   ~myclass()

   {

       std::cout << "销毁\n";

   }

};

 

voidmain()

{

   char *pcathe = newchar[1024];

   char *pcatheend = pcathe + 1024;

   std::cout << (void*)pcathe << "  " << (void*)pcatheend << std::endl;

 

   myclass *p = new(pcathe)myclass[10];//限定区域分配内存,覆盖模式

   std::cout << p <<std::endl;

 

   //delete[] p;一般不需要delete.自动覆盖

   std::cout << p <<std::endl;

 

   p =new(pcathe)myclass[10];

   std::cout << p <<std::endl;

 

   //delete[] p;//只能释放一次

   std::cout << p <<std::endl;

 

   /*

   myclass *pclass = new  myclass[10];

   std::cout << pclass <<std::endl;

   delete []pclass;

   pclass = NULL;

   std::cout << pclass <<std::endl;

   pclass = new myclass[10];

   std::cout << pclass <<std::endl;

   delete [] pclass;

   std::cout << pclass <<std::endl;

   */

 

   std::cin.get();

}

override,final的使用,两者都是针对虚函数,也就是说要有virtual关键字