zoukankan      html  css  js  c++  java
  • 第十二课、顶层父类的创建------------狄泰软件学院

    一、当代软件架构实践中的经验

    1、尽量使用单继承的方式进行系统设计(单继承+多个接口的方式)

    2、尽量保持系统中只存在单一继承树(创建一个顶层的抽象父类)

    3、尽量使用组合关系代替继承关系(后面会讲)

    不幸的事实

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

    (2)、c++编译器的差异使得同样的代码可能表现不同的行为

    如:new不成功的时候,以前的编译器都会是返回一个空指针,但是现在一般都会抛出一个异常,不同的编译器抛出的异常可能不一样,这就会使得移植性大大降低

    创建DTLib::Object类的意义

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

    (2)、定义动态内存申请的行为,提高代码的移植性

    二、完整代码

    1、头文件

    #ifndef OBJECT_H
    #define OBJECT_H
    
    namespace DTLib
    {
    
    class Object
    {
    public:
        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

    值得注意的是,重载new时函数声明后面都加上了 throw() ,表面new不成功不会抛出任何类型的异常。而将虚函数声明为纯虚函数的意义在于使其子类都用于虚函数表,能进行动态类型识别。

    2、实现文件

    #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()
    {
        cout << "Object::operator new[]" << endl;
        return malloc(size);
    }
    
    void Object::operator delete[] (void* p)
    {
        cout << "Object::operator delete[]" << endl;
        free(p);
    }
    
    Object::~Object()
    {
    
    }
    
    }
    Object.cpp

    要注意作为纯虚函数的析构函数也要进行定义(那些打印语句只是为了测试方便)

    3、测试

    #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;
    }

    通过输出的结果可以看出,new一个对象时使用了我们重载的版本,同时也含有了指向虚函数表的指针。

    三、小结

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

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

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

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

     

     

  • 相关阅读:
    Oracle如何查询不等于某数值
    《Linux系列》- 查看Linux日志
    《数据库优化》- MySQL视图
    《数据库优化》- MySQL优化
    《面试经典系列》- MySQL数据库存储引擎
    《面试经典系列》- Java获取反射机制的三种方法
    《面试经典系列》- 从底层理解==和equals的区别
    《面试经典系列》- 乐观锁和悲观锁及其应用场景
    数据结构之HashMap
    收藏学习地址
  • 原文地址:https://www.cnblogs.com/gui-lin/p/6826993.html
Copyright © 2011-2022 走看看