終於放假了,可以想干嘛干嘛了,今天早上想到以前看過幾篇大神的博客,裡面提到說用父類的指針去訪問子類的函數。。今天早上沒什麼事,就來驗證一下。
[cpp]
#include<iostream>
using namespace std;
class Base
{
public:
Base()
{
cout<<"initial Base Class"<<endl;
}
void name()
{
cout<<"Base Class name"<<endl;
}
};
class Derived1:public Base
{
public:
Derived1()
{
cout<<"initial Derived Class"<<endl;
}
void name()
{
cout<<"Derived1 Class name"<<endl;
}
};
int main()
{
Derived1 Derived1Class;
Derived1Class.name();
//這個當然是可以正常運行的
Base* BaseClassPointer;
BaseClassPointer=(Base*)&Derived1Class;
BaseClassPointer->name();
//這樣相當於把子類轉換為父類類型,然後去調用父類的name函數
return 0;
}
#include<iostream>
using namespace std;
class Base
{
public:
Base()
{
cout<<"initial Base Class"<<endl;
}
void name()
{
cout<<"Base Class name"<<endl;
}
};
class Derived1:public Base
{
public:
Derived1()
{
cout<<"initial Derived Class"<<endl;
}
void name()
{
cout<<"Derived1 Class name"<<endl;
}
};
int main()
{
Derived1 Derived1Class;
Derived1Class.name();
//這個當然是可以正常運行的
Base* BaseClassPointer;
BaseClassPointer=(Base*)&Derived1Class;
BaseClassPointer->name();
//這樣相當於把子類轉換為父類類型,然後去調用父類的name函數
return 0;
}
運行結果
[cpp]
initial Base Class
initial Derived Class //初始化Deerived類
Derived1 Class name //調用Derived類的name()
Base Class name //發生強制轉換,最終調用的是基類的name()
initial Base Class
initial Derived Class //初始化Deerived類
Derived1 Class name //調用Derived類的name()
Base Class name //發生強制轉換,最終調用的是基類的name()
在不使用虛函數的情況下,用基類的指針去訪問子類的函數。這樣做就相當於把Derived1類型的對象強制轉換為Base類型的,所以函數最終調用的是基類中的name()函數。
使用虛函數就可以實現用基類的指針去訪問子類的函數,代碼如下:
[cpp]
#include<iostream>
using namespace std;
class Base
{
public:
Base()
{
cout<<"initial Base Class"<<endl;
}
virtual void name() //用虛函數來實現
{
cout<<"Base Class name"<<endl;
}
virtual ~Base()
{
}
};
class Derived1:public Base
{
public:
Derived1()
{
cout<<"initial Derived Class"<<endl;
}
void name()
{
cout<<"Derived1 Class name"<<endl;
}
~Derived1()
{
}
};
int main()
{
Derived1 Derived1Class;
Derived1Class.name();
//這個當然是可以正常運行的
Base* BaseClassPointer = (Base*)&Derived1Class;
BaseClassPointer->name();
return 0;
}
#include<iostream>
using namespace std;
class Base
{
public:
Base()
{
cout<<"initial Base Class"<<endl;
}
virtual void name() //用虛函數來實現
{
cout<<"Base Class name"<<endl;
}
virtual ~Base()
{
}
};
class Derived1:public Base
{
public:
Derived1()
{
cout<<"initial Derived Class"<<endl;
}
void name()
{
cout<<"Derived1 Class name"<<endl;
}
~Derived1()
{
}
};
int main()
{
Derived1 Derived1Class;
Derived1Class.name();
//這個當然是可以正常運行的
Base* BaseClassPointer = (Base*)&Derived1Class;
BaseClassPointer->name();
return 0;
}
運行結果:
[cpp]
initial Base Class
initial Derived Class //初始化Derived類的兩個部分
Derived1 Class name
Derived1 Class name //最終調用的是Derived類的name()
Process returned 0 (0x0) execution time : 0.018 s
Press any key to continue.
initial Base Class
initial Derived Class //初始化Derived類的兩個部分
Derived1 Class name
Derived1 Class name //最終調用的是Derived類的name()
Process returned 0 (0x0) execution time : 0.018 s
Press any key to continue.
在類的繼承中,如果有基類指針指向派生類,那麼用基類指針delete時,如果不定義成虛函數,派生類中派生的那部分無法析構。
因此如果設計一個可能是基類的類時,最好將它的一個的析構函數設為虛函數,否則可能會造成內存洩露。