首先记住:
- 派生类引用和指针能隐式转换为基类引用和指针;
- 不存在从基类向派生类的隐式转换,即使一个基类的指针或引用绑定在一个派生类对象上,也不能执行从基类到派生类的转换。
下面我对上面两句话举例说明:
一、
class Base
{
public:
void fun1();
void fun2();
virtual void virfun();
private:
int v1;
float v2;
};
class Derived : public Base
{
public:
void selfFun();
private:
int de;
};
C++标准并没有明确规定派生类的对象在内存中如何分布,但我们可以认为Base,Derived 对象如下图所示:
注:上图是概念模型不是物理模型
因为派生类对象含有和基类相应的组成部分,所以我们能把派生类当作基类对象来使用,而且我们也能把基类的指针或引用绑定到派生类对象中的基类部分上。
Base objBase; // 基类对象
Derived objDer; // 派生类对象
Base* ptr = &objBase; // ptr 指向 Base 对象
ptr = &objDer; // ptr 执行 Derived 对象的 Base 部分
Base &ref = objDer; // ref 绑定到 Derived 对象的 Base 部分
二、
Base objBase;
Derived objDer;
Derived *ptr = &objBase; // 错误
Derived &ref = objBase; // 错误
其实第二句话很显然,如果编译器对上面的代码通过,那么 ptr->selfFun()会是怎样的结果,没人知道,因为 Base 对象不含有 selfFun() 函数,所以这种定义是错误的。