繼承那些坑
使用父類的引數呼叫子類的函式
#include <iostream>
using namespace std;
class A
{
public:
virtual void fun(int a = 1)
{
cout << "A->" << a << endl;
}
virtual void test()
{
fun();
}
};
class B : public A
{
public:
virtual void fun(int a = 0)
{
cout << "B->" << a <<endl;
}
};
int main()
{
B * p = new B;
p->test(); //B->1
return 0;
}
子類指標p指向子類,
但沒有實現父類的虛擬函式test,所以呼叫父類的虛擬函式test()
test()將會使用父類的引數呼叫子類的函式fun(),所以輸出B->1
虛解構函式
為什麼要將基類的解構函式定義為虛擬函式?
當使用基類指標指向子類時,
如果delete這個指標,就只會呼叫基類的解構函式,可能會造成記憶體洩漏
如果將基類的解構函式設定為虛擬函式,那麼delete這個指標會先呼叫子類的解構函式,再呼叫父類的解構函式。
建構函式執行順序
一個A類繼承B類,且其成員包含C類的物件c,
class A : public B
{
public:
A();
private:
C c
};
那麼在使用A類建立物件是,會先執行B的構造,再執行C的構造,再執行A自己的構造。
父類指標操作子類
#include <iostream>
using namespace std;
class A
{
public:
long a;
};
class B : public A
{
public:
long b;
};
void seta(A* data, int idx)
{
data[idx].a = 2;
}
int main(int argc, char *argv[])
{
B data[4];
for(int i=0; i<4; ++i)
{
data[i].a = 1;
data[i].b = 1;
seta(data, i);
}
for(int i=0; i<4; ++i)
{
std::cout << data[i].a << data[i].b; // 22221111
}
return 0;
}
先宣告瞭子類陣列data,然後傳入seta,此時data將會轉換為父類指標,
而父類佔4個位元組,子類佔8個位元組,就會將子類的成員也給改變。
相關文章
- 繼承那些事繼承
- odoo 繼承(owl繼承、web繼承、view繼承)Odoo繼承WebView
- JavaScript物件導向那些東西-繼承JavaScript物件繼承
- 原型,繼承——原型繼承原型繼承
- 菱形繼承,虛繼承繼承
- 多繼承 與 多重繼承繼承
- C++繼承詳解:共有(public)繼承,私有(private)繼承,保護(protected)繼承C++繼承
- CSS:line-height繼承時的坑CSS繼承
- 三種繼承的方法:public 繼承/private繼承/protected繼承詳解及區別繼承
- Javascript繼承4:潔淨的繼承者—-原型式繼承JavaScript繼承原型
- Javascript繼承2:建立即繼承—-建構函式繼承JavaScript繼承函式
- 繼承繼承
- C++繼承一之公有繼承C++繼承
- JS原型繼承和類式繼承JS原型繼承
- C++中公有繼承、保護繼承、私有繼承的區別C++繼承
- 公有繼承、私有繼承和保護繼承之間的對比繼承
- day23:單繼承&多繼承&菱形繼承&__init__魔術方法繼承
- 類的繼承_子類繼承父類繼承
- JavaScript繼承JavaScript繼承
- JavaScript 繼承JavaScript繼承
- 多繼承繼承
- Java繼承Java繼承
- javascript:繼承JavaScript繼承
- swift繼承Swift繼承
- js繼承JS繼承
- 虛繼承繼承
- 10 #### 繼承繼承
- python 基礎之繼承、重寫、多繼承Python繼承
- PostgreSQL 表繼承SQL繼承
- 16-繼承繼承
- 粗談繼承繼承
- 原型和繼承原型繼承
- javascript之繼承JavaScript繼承
- JavaScript class 繼承JavaScript繼承
- JavaScript extends 繼承JavaScript繼承
- Javascrip—繼承(10)Java繼承
- 類的繼承繼承
- Swift-繼承Swift繼承