派生類和基類的轉化

一、開宗明義

1.派生類到基類的轉化存在,這是理解多態的基礎;

2.基類到派生類的轉化不存在;

3. 派生類到基類的轉化包括以下三種情況:

  • 派生類對象轉化爲基類對象
  • 基類對象指針指向派生類對象
  • 用派生類對象初始化積累對象的引用

 二、派生類到基類的轉化 

1.派生類對象轉化爲基類對象

轉化的結果就是:派生類新增的數據類型全部捨棄,而調用函數時只能調用基類的函數。這就是一個砍掉的派生類多餘部分的過程。派生類對象也是基類對象。

#include <iostream>
using namespace std;
//基類
class A {
public:
	A(int a) { m_a = a; }
public:
	void display();
public:
	int m_a;
};
void A::display() {
	cout << "基類A: m_a=" << m_a << endl;
}
//派生類
class B : public A {
public:
	B(int a, int b) : A(a), m_b(b) { }
public:
	void display();
public:
	int m_b;
};
void B::display() {
	cout << "派生類B: m_a=" << m_a << ", m_b=" << m_b << endl;
}

int main() {
	A a(10);
	B b(66, 99);
	cout << "賦值前:" << endl;
	a.display();
	b.display();
	cout << "--------------" << endl;
	cout << "賦值前:" << endl;
	a = b;
	a.display();
	b.display();
	return 0;
}

 

2.基類對象指針指向派生類對象

引用跟指針基本沒有區別,引用本質上是指針,是個指針常量。所以第二種、第三種轉化可以認爲效果是一樣的。

 基類對象指針只能調用基類中有的部分,不能通過基類指針訪問基類沒有而派生類中有的成員。跟第一種情況是一樣的。

#include <iostream>
using namespace std;
//基類
class A {
public:
	A(int a) { m_a = a; }
public:
	void display();
public:
	int m_a;
};
void A::display() {
	cout << "基類A: m_a=" << m_a << endl;
}
//派生類
class B : public A {
public:
	B(int a, int b) : A(a), m_b(b) { }
public:
	void display();
public:
	int m_b;
};
void B::display() {
	cout << "派生類B: m_a=" << m_a << ", m_b=" << m_b << endl;
}

int main() {
	A a(10);
	B b(66, 99);
	cout << "賦值前:" << endl;
	a.display();
	b.display();

	cout <<endl<< "a=b 賦值後:" << endl;
	a = b;
	b.m_a = 1000;
	b.display();

	cout <<endl<< "A*ps=&b賦值後:" << endl;
	A*ps = &b;
	ps->m_a = 100;
	//ps->m_b = 100;錯誤,不存在m_b
	b.display();
	return 0;
}

 

 可以發現,無論是派生類對象直接給基類對象賦值,或者是基類指針指向派生類。
 基類操作之後派生類都會發生變化,所以轉化過程並沒有開闢一塊新的內存。

參考資料:

 https://www.cnblogs.com/piginthetree/p/3891885.html

http://c.biancheng.net/view/260.html

 

 

 

 

 

 

 

 

發佈了60 篇原創文章 · 獲贊 67 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章