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();
運作結果:
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
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()
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);
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;
*/