向上转换和向下转换:

  • 向上转换(Upcasting):将派生类指针或引用转换为基类指针或引用。这总是安全的,因为派生类包含基类的所有内容。具体说,转换为基类后,只能访问基类成员,而派生类又一定会有基类所有内容,所以安全。

    • 基类指针可以指向基类对象与派生类对象,因为基类指针只能访问基类成员,而不管指向基类还是派生类,都能访问到基类成员。
  • 向下转换(Downcasting):将基类指针或引用转换为派生类指针或引用。这可能不安全,因为基类指针可能实际上并不指向一个派生类对象(可能指向基类对象)。

    • 根本原因是,基类指针可能指向基类对象或派生类对象
      • 指向基类的话,如果能让你直接转换为派生类指针,程序员就容易犯罪了,真转了的话,该指针能够访问派生类的额外内容,但基类并没有这些内容,所以会有问题。
      • 指向派生类对象的话还好说,指针转换为派生类的话,想访问额外内容也确实可以访问。
    • 反正转换的时候用Dynamic_cast,如果该基类指针指向了基类指针,会转换失败,就直接自动指向空指针了。如果指向的是派生类,那成功。

指针类型的作用

a) 类型安全:编译器可以检查指针操作是否合法。 b) 内存解释:告诉编译器如何解释指针指向的内存。 c) 指针算术:不同类型的指针在进行加减操作时步长不同。 d) 函数重载:允许基于指针类型进行函数重载。

指针类型主要是一个编译时的概念。在运行时,CPU只看到内存地址,不关心类型。

这个构造函数接受一个 const 引用参数 rhs,它表示将要被拷 贝的对象。该构造函数做了以下工作:

  1. 首先,它通过使用基类的构造函数来初始化自身(Base(rhs)) 。
  2. 然后,它分配内存来保存 _pderived 的拷贝(_pderived = new char[strlen(rhs._pderived) + 1]())。注意,这里使用了动 态内存分配(new[])和 strlen 函数。
  3. 最后,它通过 strcpyrhs._pderived 的内容复制到 _pderived 中。

这个构造函数的目的是复制 rhs 对象中的所有成员,并将其作为 新的对象返回。

赋值运算符

Derived & operator=(const Derived & rhs){
    cout << "Derived & operator=(const Derived &)" <<
endl;
    if(this != &rhs){
        //显式调用基类的赋值运算符函数
        Base::operator=(rhs);//关键
        delete [] _pderived;
        _pderived = new char[strlen(rhs._pderived) + 1]();
        strcpy(_pderived,rhs._pderived);
        _derived = rhs._derived;
    }
    return *this;
}

这个赋值运算符函数接受一个 const 引用参数 rhs,它表示要 被赋值的对象。该函数做了以下工作:

  1. 首先,它检查是否 thisrhs 是指向同一个对象。如果是 ,则返回当前对象(return *this;)。
  2. 然后,它通过使用基类的赋值运算符函数来初始化自身( Base::operator=(rhs))。注意,这里显式地调用了基类的赋值运 算符函数。
  3. 接下来,它释放 _pderived 中的旧数据,并重新分配新的内存 空间(delete [] _pderived; _pderived = new char[strlen(rhs._pderived) + 1]())。
  4. 最后,它通过 strcpyrhs._pderived 的内容复制到 _pderived 中,然后赋值 _derived 到其对应的成员。

这个赋值运算符函数的目的是将 rhs 对象中的所有成员赋值给当 前对象,并返回当前对象本身。

基类成员 Public继承 Protected继承 Private继承
Public Public Protected Private
Protected Protected Protected Private
Private 不可访问 不可访问 不可访问

更新时间: