当代软件架构实践中的经验
- 尽量使用单重继承的方式进行系统设计
- 尽量保持系统中只存在单一的继承树
- 尽量使用组合关系代替继承关系
不幸的事实
- C++ 语言的灵活性使得代码可以存在多个继承树
- C++ 编译器的差异使得同样的代码可能表现不同的行为
new 操作如果失败会发生什么?
- 老版编译器:返回空
- 新版编译器:抛出异常
创建 DTLib::Object 类的意义
- 遵循经典设计准则,所有数据都继承自 Object (单一继承树)
- 定义动态内存申请的行为,提高代码的移植性(统一编译器行为)
顶层父类的接口定义
class Object
{
public:
void *operator new (unsigned int size) noexcept;
void operator delete (void *p);
void *operator new[] (unsigned int size) noexcept;
void operator delete[] (void *p);
virtual ~Object() = 0;
};
编程实验:顶层父类的创建
文件:Object.h
#ifndef OBJECT_H
#define OBJECT_H
namespace DTLib
{
class Object
{
public:
void *operator new (unsigned int size) noexcept;
void operator delete (void *p);
void *operator new[] (unsigned int size) noexcept;
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) noexcept
{
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) noexcept
{
return malloc(size);
}
void Object::operator delete[] (void *p)
{
free(p);
}
Object::~Object()
{
}
}
文件:main.cpp
#include "Object.h"
#include <cstdlib>
#include <iostream>
using namespace std;
namespace DTLib
{
void *Object::operator new (unsigned int size) noexcept
{
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) noexcept
{
return malloc(size);
}
void Object::operator delete[] (void *p)
{
free(p);
}
Object::~Object()
{
}
}#include <iostream>
#include "SmartPointer.h"
#include "Exception.h"
#include "Object.h"
using namespace std;
using namespace DTLib;
class Base : public Object
{
int i;
int j;
};
class Derived : public Base
{
int k;
};
int main()
{
Object *obj1 = new Base;
Object *obj2 = new Derived;
cout << "obj1 = " << obj1 << endl;
cout << "obj2 = " << obj2 << endl;
delete obj1;
delete obj2;
return 0;
}
输出:
Object::operator new : 12
Object::operator new : 16
obj1 = 0xe66f38
obj2 = 0xe66f50
Object::operator delete : 0xe66f38
Object::operator delete : 0xe66f50
注:C++规定,但凡定义了析构函数,不管析构函数是不是纯虚函数,都需要提供具体实现。(因为父类析构函数需要被子类隐含调用)
小结
- Object 类是 DTLib 中数据结构类的顶层父类
- Object 类用于统一动态内存的申请行为
- 在堆中创建 Object 子类的对象,失败时返回 NULL 值
- Object 类为纯虚父类,所有子类都能进行动态类型识别
参考课程
狄泰软件学院《C++深度解析教程》
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。