• C++学习笔记13-类继承


     1.  类模板的 static 成员[不同于C#中的static]

    类模板能够像随意其它类一样声明static 成员。下面代码:

     template <class T> class Foo {
     public:
     static std::size_t count() { return ctr; }
     // other interface members
     private:
     static std::size_t ctr;
     // other implementation members
     };

    定义了名为Foo 的类模板,它有一个名为count 的public static 成员函数和一个名为ctr 的private static 数据成员。

    Foo 类的每一个实例化有自己的static 成员:

     // Each object shares the same Foo<int>::ctr and Foo<int>::count members
     Foo<int> fi,fi2, fi3;
     // has static members Foo<string>::ctr and Foo<string>::count
     Foo<string> fs;

    每一个实例化表示截然不同的类型,所以给定实例外全部对象都共享一个static 成员。因此,Foo<int>类型的随意对象共享同一static 成员ctr,Foo<string> 类型的对象共享还有一个不同的 ctr 成员。

    使用类模板的static 成员通常,能够通过类类型的对象訪问类模板的static 成员,或者通过使用作用域操作符直接訪问成员。当然,当试图通过类使用static 成员的时候,必须引用实际的实例化:

     Foo<int> fi, fi2;                           // instantiates Foo<int> class
     size_t ct =Foo<int>::count();               // instantiates Foo<int>::count
     ct = fi.count();                            // ok: uses Foo<int>::count
     ct = fi2.count();                           // ok: uses Foo<int>::count
     ct = Foo::count();                          // error: which template instantiation?

    与随意其它成员函数一样,static成员函数仅仅有在程序中使用时才进行实例化。

    2. 句柄类

    类管理继承层次中对象的指针,句柄的用户不必管理指向这些对象的指针,用户代码能够使用句柄类来编写。

    句柄可以动态分配和释放相关继承类的对象,而且将全部“实际”工作转发给继承层次中的底层类。

    3. 转换与多个基类

     class X { ... };
     class A { ... };
     class B : public A {... };
     class C : private B {... };
     class D : public X,public C { ... };
     // 假设有,以下转换中哪些是不同意的?
     D *pd = new D;
     (a) X *px = pd;
     (c) B *pb = pd;  // X, B is private
     (b) A *pa = pd;  // X, B is private
     (d) C *pc = pd;

    4. 虚继承

    虚继承是一种机制,类通过虚继承指出它希望共享其虚基类的状态。在虚继承下,对给定虚基类,不管该类在派生层次中作为虚基类出现多少次,仅仅继承一个共享的基类子对象。共享的基类子对象称为虚基类。

    5. 如何构造虚继承的对象

    让我们看看虚继承情况下如何构造对象。

     Bear::Bear(std::string name, bool onExhibit): ZooAnimal(name,onExhibit, "Bear") { }
     Raccoon::Raccoon(std::string name, boolonExhibit) : ZooAnimal(name,onExhibit, "Raccoon") { }
     // 尽管ZooAnimal 不是Panda 的直接基类,可是Panda 构造函数也初始化 ZooAnimal 基类:
     Panda::Panda(std::string name, bool onExhibit) : ZooAnimal(name,onExhibit, "Panda"), Bear(name,onExhibit),Raccoon(name, onExhibit), Endangered(Endangered::critical), sleeping_flag(false){ }
     
    Bear winnie("pooh");           // Bear constructor initializes ZooAnimal
    Raccoon meeko("meeko");        // Raccoon constructor initializesZooAnimal
    Panda yolo("yolo");            // Panda constructor initializes ZooAnimal

    当创建Panda 对象的时候,

    1. 首先使用构造函数初始化列表中指定的初始化式构造ZooAnimal 部分。

    2. 接下来,构造Bear 部分。忽略Bear 的用于ZooAnimal 构造函数初始化列表的初始化式。

    3. 然后,构造Raccoon 部分,再次忽略ZooAnimal 初始化式。

    4. 最后,构造Panda 部分。

    假设Panda 构造函数不显式初始化ZooAnimal 基类,就使用ZooAnimal 默认构造函数;假设ZooAnimal 没有默认构造函数,则代码出错。当编译Panda 构造函数的定义时,编译器将给出一个错误信息。

    6. 小结

    在抛出异常的时候,会终止当前正在运行的函数并開始查找近期的catch 子句,在查找catch子句的时候,作为异常处理的一部分,将撤销退出函数内部定义的局部变量。这样的撤销对象提供了一个重要的编程技术,称为“资源分配即初始化”(RAII)。命名空间是一种机制,用于管理用独立供应商开发的代码建立的大型复杂应用程序。一个命名空间就是一个作用域,当中能够定义对象、类型、函数、模板和其它命名空间。标准库就定义在名为std 的命名空间中。

    通过using 声明,当前作用域中就都能够訪问某个命名空间中的名字了。

    当然,也能够通过using 指示将一个命名空间中的全部名字带入当前作用域,但这样的做法非常不安全。

    从概念上来看,多重继承非常easy:派生类能够继承多个直接基类,派生类对象由派生部分和每一个基类所贡献的基类部分构成。尽管多重继承概念简单,但细节可能非常复杂,尤其是,继承多个基类引入了新的名字冲突可能性,而且会导致对对象基类中的名字的引用出现二义性。

    一个类继承多个直接基类的时候,那些类有可能本身还共享还有一个基类。在这样的情况下,中间类能够选择使用虚继承,声明愿意与层次中虚继承同一基类的其它类共享虚基类。用这样的方法,后代派生类中将仅仅有一个共享虚基类的副本。

  • 相关阅读:
    更新glibc,删除libc库后,命令行都不能使用了
    进程和线程、协程的区别
    PMP项目管理--资源管理
    清除缓存 echo 1/2/3 > /proc/sys/vm/drop_caches
    gdb malloc方法
    随时更新---能力集
    输出gdb调试信息到文件中
    主动生成core文件 gcore +pid
    PMP项目管理--风险管理
    linux后台程序
  • 原文地址:https://www.cnblogs.com/zfyouxi/p/4485839.html
Copyright © 2020-2023  润新知