天天看點

override,final的使用,兩者都是針對虛函數,也就是說要有virtual關鍵字



1.override,final的使用,兩者都是針對虛函數,也就是說要有virtual關鍵字

#include

<iostream>

//c++中的final和override主要是針對虛函數

//加了final表示拒絕重寫,這是為了使某些情況下,拒絕接口的重寫

//override,聲明重寫父類的方法,前提是要有virtual關鍵字修飾函數。

//當父類沒有接口,會提示錯誤

class

ye

{

public:

//final修飾的函數必須是虛函數,通過這種方式避免重寫了一些老的接口

virtual

void

print()

final

//加了final表示虛函數無法重寫了

std::cout

<< "爺爺\n";

}

run()

<< "爺爺run\n";

};

ba :public

override

<< "爸爸run\n";

main()

ba

ba1;

ba1.run(); 

//結果是:爸爸run

std::cin.get();

2.rtti

實時類類型檢測

//rtti,實時類類型檢測

//typeid,dynamic_cat必須依賴于虛函數表

//類型不比對轉換失敗,傳回為空,類型安全

//成員變量的覆寫

//虛函數有虛函數表确定資料類型

a

int

num;

static

data;

<< "a run \n";

//對a中的靜态變量進行初始化

a::data

= 1;

b :public

num = 0;

<< "b run\n";

test()

<< num <<

"\n";

<< "b test\n";

b::data

= 2;

a1;

b

b1;

a *p1

= &a1;

a *p2

= &b1;

b *p3(nullptr);

//p3 = static_cast<b *>(p1);//直接賦位址,不安全,與虛函數無關

p3 =

reinterpret_cast<b

*>(p2);

<< p3 <<

p3->test();

//此次運作結果:

//008ffe70

//0

//b test

3.c函數指針複習

<stdlib.h>

add(int

a,int

b)

return

a +

b;

printf("\nrun");

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();

運作結果:

override,final的使用,兩者都是針對虛函數,也就是說要有virtual關鍵字

4.cpp函數指針

<< a +

b <<

std::endl;

void(*p)(int,

add;

p(1, 2);

(*p)(1,2);

//函數指針,會被當做指針來處理,*p與p效果一樣

(*************p)(1,2);//函數指針,會被當做指針來處理,*p與p效果一樣

(*&p)(1,2);

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

<< (void *)p

<< " 

" << (void

*)(*p) <<

<< typeid(p).name()

<< std::endl;

<< typeid(*p).name()

<< typeid(&p).name()

<< typeid(*&p).name()

//c++編譯器會自動将*p處理為p

override,final的使用,兩者都是針對虛函數,也就是說要有virtual關鍵字

5.類成員函數指針數組

<stdio.h>

//類成員函數指針,類成員函數指針數組,類成員二級函數指針

com

private:

a;

com(int

x,

y) :a(x),

b(y)

int 

jia(int

a,

jian(int

a -

cheng(int

a *

chu(int

a /

com1(100, 20);

auto

fun1 = &com::jia;

int(com::*p)(int,

int) = &com::jia; 

//注意這裡要加上對象名

<< (com1.*p)(10,

20) << std::endl;//引用對象,類成員函數指針

<< typeid(fun1).name()

override,final的使用,兩者都是針對虛函數,也就是說要有virtual關鍵字

5.cpp函數指針數組

typedef

int);//為函數指針定義别名p

com1(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 (int

i = 0;

i < 4;

i++)

<< (com1.*fun1[i])(10,

20) << std::endl;

int(com::**funp)(int,

fun1;//指向類成員函數指針的指針

for (;

funp <

fun1 + 4;funp++)

<< (com1.**funp)(10,

printf("%p",*funp);

i < 4;i++)

func =

fun1[i];

<< typeid(func).name()

printf("%p",

func);

override,final的使用,兩者都是針對虛函數,也就是說要有virtual關鍵字

6.進階new對象

#include<iostream>

myclass

myclass()

<< "建立\n";

~myclass()

<< "銷毀\n";

char *pcathe

= new

char[1024];

char *pcatheend

= pcathe + 1024;

<< (void*)pcathe

<< "  

" << (void*)pcatheend

myclass *p

= new(pcathe)myclass[10];//限定區域配置設定記憶體,覆寫模式

<< p <<

//delete[] p;一般不需要delete.自動覆寫

p =

new(pcathe)myclass[10];

//delete[] p;//隻能釋放一次

/*

myclass *pclass = new  myclass[10];

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

delete []pclass;

pclass = null;

pclass = new myclass[10];

delete [] pclass;

*/

繼續閱讀