一、开宗明义
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