类型转换规则:
- 公有派生类对象可以被当作基类的对象使用,反之则不可
- 派生类的对象可以隐含转换为基类对象
- 派生类的对象可以初始化基类的引用
- 派生类的指针可以隐含转换为基类的指针
- 通过基类对象名,指针只能使用从基类继承的成员
#include<iostream>
using namespace std;
class BaseA
{
public:
BaseA(int x, int y)
{
this->x = x;
this->y = y;
}
void Disp()
{
printf("x = %d y = %d\n", x, y);
}
private:
int x, y;
};
class B: public BaseA
{
public:
B(int x, int y, int z): BaseA(x, y), z(z) {}
void Disp()
{
BaseA::Disp();
printf("z = %d\n", z);
}
private:
int z;
};
void Print1(BaseA &Q) { Q.Disp(); }
void Print2(B &Q) { Q.Disp(); }
void Print3(BaseA Q) { Q.Disp(); }
void Print4(B Q) { Q.Disp(); }
int main()
{
BaseA a(3, 4);
a.Disp();
B b(10, 20, 30);
b.Disp(); puts("");
BaseA * pa;
B * pb;
pa = &a;
pa->Disp();
pb = &b;
pb->Disp(); puts("");
pa = &b; //pa为基类指针,指向派生类对象是合法的,因为派生类对象也是基类对象
pa->Disp(); puts(""); //这里调用的是基类的Disp(),如果要实现调用派生类的Disp函数,需要用虚函数实现多态性
// pb = &a; //非法,派生类指针不能指向基类对象
Print1(b); //因为派生类对象也是基类对象,所以可以将派生类对象赋值给基类引用,函数仍然会调用基类的Disp()
Print2(b);
Print3(b); //派生类对象赋值给基类对象时,派生类对象基类部分被复制给形参
Print4(b); puts("");
Print1(a);
Print3(a); puts("");
// Print2(a); Print4(a); //非法,不能用基类对象给派生类引用赋值,也不能用基类对象给派生类对象赋值
//pb = pa; //非法,不能用基类指针给派生类指针赋值
pa = &a;
pb = (B*)pa; //可以强制转换,但是非常不安全
pb->Disp(); //a中没有p成员,而这里会调用派生类的Disp(),导致输出p为垃圾值
return 0;
}