• 第12课 顶层父类的创建


    1. 当代软件架构实践中的经验

    (1)尽量使用单重继承的方式进行系统设计

    (2)尽量保持系统中只存在单一的继承树

    (3)尽量使用组合关系代替继承关系

    2. 不幸的事实

    (1)C++语言的灵活性使得代码中可以存在多个继承树

    (2)C++编译器的差异使得同样的代码可能表现不同的行为(如new操作结果失败,有的编译器会返回NULL,有的会抛std::bad_alloc异常)

    3. 创建DTLib::Object类的意义

    (1)遵循经典设计准则,所有数据结构都继承自Object类

    (2)定义动态内存申请的行为,提高代码的移植性(即重载operator new,让new的失败时在不同的编译器下都能返回NULL,而不是抛出异常或返回NULL等多种结果)

    【编程实验】顶层父类的创建

    //Object.h

    #ifndef _OBJECT_H_
    #define _OBJECT_H_
    
    namespace DTLib
    {
    
    class Object
    {
    public:
        //以下四个重载函数用于统一不同编译器new失败时的结果不同的问题。
        //throw()表示不抛出异常,即如果申请内请失败时,统一返回NULL而不抛异常
        void* operator new(unsigned int size) throw();
        void operator delete(void* p);
        void* operator new[](unsigned int size) throw();
        void operator delete[](void* p);
    
        virtual ~Object() = 0;
    };
    
    }
    
    
    #endif // _OBJECT_H_

    //Object.cpp

    #include "Object.h"
    #include <cstdlib>
    #include <iostream>
    
    using namespace std;
    
    namespace DTLib {
    
    void * Object::operator new(unsigned int size)  throw()
    {
        cout <<"Object::operator new: " << size << endl;
        return malloc(size);
    }
    
    void Object::operator delete(void *p)
    {
        cout <<"Object::operator delete: " << p << endl;
        free(p);
    }
    
    void *Object::operator new[](unsigned int size) throw()
    {
        //当用new Test[5]时,只须传入数组元素的个数,编译器会向operator new[](...)函数的参数
        //传入5*sizeof(Test) + sizeof(unsigned int),其中的sizeof(unsigned int)为额外
        //空间,用于保存元素的个数。
        cout <<"Object::operator new[]: " << size << endl;
        return malloc(size);
    }
    
    void Object::operator delete[](void *p)
    {
        cout <<"Object::operator delete[]: " << p << endl;
        free(p);
    }
    
    Object::~Object()
    {
    
    }
    
    
    }

    //main.cpp

    #include <iostream>
    #include "Object.h"
    using namespace std;
    using namespace DTLib;
    
    class Test : public Object
    {
    public:
        int i;
        int j;
    };
    
    class Child : public Test
    {
    public:
        int k;
    };
    
    int main()
    {
        Object* obj1 = new Test();
        Object* obj2 = new Child();
    
        cout << "obj1 = " << obj1 << endl;
        cout << "obj2 = " << obj2 << endl;
    
        delete obj1;
        delete obj2;
    
        return 0;
    }
    /*输出结果
    Object::operator new: 12
    Object::operator new: 16
    obj1 = 0x3d12a8
    obj2 = 0x3d12c0
    Object::operator delete: 0x3d12a8
    Object::operator delete: 0x3d12c0
    */

    4. 小结

    (1)Object是DTLib中数据结构类的顶层父类

    (2)Object类用于统一动态内存申请的行为

    (3)在堆中创建Object子类的对象,失败时返回NULL值

    (4)Object类为纯虚父类,所有子类都能进行动态类型识别。

  • 相关阅读:
    【BZOJ】1006: [HNOI2008]神奇的国度 弦图消除完美序列问题
    【BZOJ】1015: [JSOI2008]星球大战starwar
    poj 2001 Shortest Prefixes trie入门
    hdu 1251 统计难题 trie入门
    hdu 4570 Multi-bit Trie 区间DP入门
    Lucas定理的理解与应用
    hdu 3944 DP? 组合数取模(Lucas定理+预处理+帕斯卡公式优化)
    组合数模板
    如何使用弹窗来让用户订阅电子杂志
    分享一则电子邮件营销案例
  • 原文地址:https://www.cnblogs.com/5iedu/p/6754344.html
Copyright © 2020-2023  润新知