1. 父子間的賦值兼容
子類對(duì)象可以當(dāng)作父類對(duì)象使用(兼容性)
- 子類對(duì)象可以直接賦值給父類對(duì)象
- 子類對(duì)象可以直接初始化父類對(duì)象
- 父類指針可以直接指向子類對(duì)象
- 父類引用可以直接引用子類對(duì)象
編程說明: 子類對(duì)象的兼容性問題
#include <iostream>
#include <string>
using namespace std;
class Parent
{
public:
int mi;
void add(int i)
{
mi += i;
}
void add(int x, int y)
{
mi += (x + y);
}
};
class Child : public Parent
{
public:
int mi;
void add(int x, int y, int z)
{
mi += (x + y + z);
}
};
int main()
{
Parent p;
Child c;
p = c;
Parent p1(c);
Parent& rp = c;
Parent* pp = &c;
rp.mi = 100;
rp.add(5); //沒有發(fā)生同名?覆蓋
rp.add(10, 10); //沒有發(fā)生同名?覆蓋
/* 為什么編譯不過 */
// pp->mv = 100;
// pp->add(1, 10, 100);
return 0;
}
- 當(dāng)使用父類指針(引用)指向子類對(duì)象時(shí):
(1) 子類對(duì)象退化為父類對(duì)象
(2) 只能訪問父類中定義的成員
(3) 可以直接訪問被子類覆蓋的同名成員
2. 特殊的同名函數(shù)
子類中可以重定義父類中已經(jīng)存在的成員函數(shù),這種重定義發(fā)生在繼承中,叫做函數(shù)重寫。
函數(shù)重寫是同名覆蓋的一種特殊情況
編程說明:函數(shù)重寫初探
#include <iostream>
#include <string>
using namespace std;
class Parent
{
public:
void print()
{
cout << "I'm Parent." << endl;
}
};
class Child : public Parent
{
public:
void print() // 函數(shù)重寫
{
cout << "I'm Child." << endl;
}
};
int main()
{
Child c;
c.print();
return 0;
}
輸出結(jié)果:
I'm Child.
3. 思考:當(dāng)函數(shù)重寫遇上賦值兼容會(huì)發(fā)生什么?
- 編程說明:賦值兼容的問題
#include <iostream>
#include <string>
using namespace std;
class Parent
{
public:
void print()
{
cout << "I'm Parent." << endl;
}
};
class Child : public Parent
{
public:
void print() // override function
{
cout << "I'm Child." << endl;
}
};
void how_to_print(Parent* p)
{
p->print();
}
int main()
{
Parent p;
Child c;
how_to_print(&p); // Expected to print : I'm Parent.
how_to_print(&c); // Expected to print : I'm Child.
return 0;
}
輸出結(jié)果:
I'm Parent.
I'm Parent.
問題分析:
(1) 編譯期間,編譯器只能根據(jù)指針的類型判斷所指向的對(duì)象;
(2) 根據(jù)賦值兼容,編譯器認(rèn)為父類指針指向的是父類對(duì)象;
(3) 因此,編譯結(jié)果只可能是調(diào)用父類中定義的同名函數(shù)
4. 問題:編譯器的處理方法是合理的嗎?是期望的嗎?
合理,但不是期望的。
5. 小結(jié)
- 子類對(duì)象可以當(dāng)作父類對(duì)象使用(賦值兼容)
- 父類指針可以正確的指向子類對(duì)象
- 父類引用可以正確的代表子類對(duì)象
- 子類中可以重寫父類中的成員函數(shù)
