标签:idp 运行 示例 tor col 注意事项 namespace 错误 opera
参考前文传送门:
C++解析(29):类型识别
C++解析(31):自定义内存管理(完)
C++解析-外传篇(1):异常处理深度解析
C++解析-外传篇(2):函数的异常规格说明
C++解析-外传篇(3):动态内存申请的结果
当代软件架构实践中的经验:
不幸的事实:
(编译器的差异:new操作如果失败会发生什么?)
创建 StLib::Object 类的意义:
顶层父类的接口定义:

示例——顶层父类的创建:
创建Object.h
#ifndef OBJECT_H
#define OBJECT_H
namespace StLib
{
class Object
{
public:
    void* operator new (size_t size) throw();
    void operator delete (void* p);
    void* operator new[] (size_t 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 StLib
{
void* Object::operator new (size_t 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[] (size_t size) throw()
{
    return malloc(size);
}
void Object::operator delete[] (void* p)
{
    free(p);
}
Object::~Object()
{
}
}
main.cpp测试
#include <iostream>
#include "Object.h"
using namespace std;
using namespace StLib;
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: 16
Object::operator new: 24
obj1 = 0000025D8EA46F00
obj2 = 0000025D8EA42D50
Object::operator delete: 0000025D8EA46F00
Object::operator delete: 0000025D8EA42D50
遵循经典设计准则——StLib中的所有类位于单一的继承树:

改进的关键点:
最终Object类:
Object.h
#ifndef OBJECT_H
#define OBJECT_H
namespace StLib
{
class Object
{
public:
    void* operator new (size_t size) throw();
    void operator delete (void* p);
    void* operator new[] (size_t 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 StLib
{
void* Object::operator new (size_t size) throw()
{
    return malloc(size);
}
void Object::operator delete (void* p)
{
    free(p);
}
void* Object::operator new[] (size_t size) throw()
{
    return malloc(size);
}
void Object::operator delete[] (void* p)
{
    free(p);
}
Object::~Object()
{
}
}
改进SmartPointer类:
SmartPointer.h
#ifndef SMARTPOINTER_H
#define SMARTPOINTER_H
#include "Object.h"
namespace StLib
{
template <typename T>
class SmartPointer : public Object
{
protected:
    T* m_pointer;
public:
    SmartPointer(T* p = NULL)
    {
        m_pointer = p;
    }
    SmartPointer(const SmartPointer<T>& obj)
    {
        m_pointer = obj.m_pointer;
        const_cast<SmartPointer<T>&>(obj).m_pointer = NULL;
    }
    SmartPointer<T>& operator= (const SmartPointer<T>& obj)
    {
        if( this != &obj )
        {
            delete m_pointer;
            m_pointer = obj.m_pointer;
            const_cast<SmartPointer<T>&>(obj).m_pointer = NULL;
        }
        return *this;
    }
    T* operator-> ()
    {
        return m_pointer;
    }
    T& operator* ()
    {
        return *m_pointer;
    }
    bool isNull()
    {
        return (m_pointer == NULL);
    }
    T* get()
    {
        return m_pointer;
    }
    ~SmartPointer()
    {
        delete m_pointer;
    }
};
}
#endif // SMARTPOINTER_H
改进Exception类:
Exception.h
#ifndef EXCEPTION_H
#define EXCEPTION_H
#include "Object.h"
using namespace std;
namespace StLib
{
// 使用宏简化代码
#define THROW_EXCEPTION(e, m) (throw e(m, __FILE__, __LINE__))
class Exception : public Object
{
protected:
    char* m_message;
    char* m_location;
    void init(const char* message, const char* file, int line);
public:
    Exception(const char* message);
    Exception(const char* file, int line);
    Exception(const char* message, const char* file, int line);
    Exception(const Exception& e);
    Exception& operator= (const Exception& e);
    virtual const char* message() const;
    virtual const char* location() const;
    virtual ~Exception() = 0;
};
/*
 * 计算异常
 */
class ArithmeticException : public Exception
{
public:
    ArithmeticException() : Exception(0) { }
    ArithmeticException(const char* message) : Exception(message) { }
    ArithmeticException(const char* file, int line) : Exception(file, line) { }
    ArithmeticException(const char* message, const char* file, int line) : Exception(message, file, line) { }
    ArithmeticException(const ArithmeticException& e) : Exception(e) { }
    ArithmeticException& operator= (const ArithmeticException& e)
    {
        Exception::operator= (e);
        return *this;
    }
};
/*
 * 空指针异常
 */
class NullPointerException : public Exception
{
public:
    NullPointerException() : Exception(0) { }
    NullPointerException(const char* message) : Exception(message) { }
    NullPointerException(const char* file, int line) : Exception(file, line) { }
    NullPointerException(const char* message, const char* file, int line) : Exception(message, file, line) { }
    NullPointerException(const NullPointerException& e) : Exception(e) { }
    NullPointerException& operator= (const NullPointerException& e)
    {
        Exception::operator= (e);
        return *this;
    }
};
/*
 * 越界异常
 */
class IndexOutOfBoundsException : public Exception
{
public:
    IndexOutOfBoundsException() : Exception(0) { }
    IndexOutOfBoundsException(const char* message) : Exception(message) { }
    IndexOutOfBoundsException(const char* file, int line) : Exception(file, line) { }
    IndexOutOfBoundsException(const char* message, const char* file, int line) : Exception(message, file, line) { }
    IndexOutOfBoundsException(const NullPointerException& e) : Exception(e) { }
    IndexOutOfBoundsException& operator= (const NullPointerException& e)
    {
        Exception::operator= (e);
        return *this;
    }
};
/*
 * 内存不足异常
 */
class NoEnoughMemoryException : public Exception
{
public:
    NoEnoughMemoryException() : Exception(0) { }
    NoEnoughMemoryException(const char* message) : Exception(message) { }
    NoEnoughMemoryException(const char* file, int line) : Exception(file, line) { }
    NoEnoughMemoryException(const char* message, const char* file, int line) : Exception(message, file, line) { }
    NoEnoughMemoryException(const NoEnoughMemoryException& e) : Exception(e) { }
    NoEnoughMemoryException& operator= (const NoEnoughMemoryException& e)
    {
        Exception::operator= (e);
        return *this;
    }
};
/*
 * 参数错误异常
 */
class InvalidParameterException : public Exception
{
public:
    InvalidParameterException() : Exception(0) { }
    InvalidParameterException(const char* message) : Exception(message) { }
    InvalidParameterException(const char* file, int line) : Exception(file, line) { }
    InvalidParameterException(const char* message, const char* file, int line) : Exception(message, file, line) { }
    InvalidParameterException(const InvalidParameterException& e) : Exception(e) { }
    InvalidParameterException& operator= (const InvalidParameterException& e)
    {
        Exception::operator= (e);
        return *this;
    }
};
/*
 * 非法操作异常
 */
class InvalidOperationException : public Exception
{
public:
    InvalidOperationException() : Exception(0) { }
    InvalidOperationException(const char* message) : Exception(message) { }
    InvalidOperationException(const char* file, int line) : Exception(file, line) { }
    InvalidOperationException(const char* message, const char* file, int line) : Exception(message, file, line) { }
    InvalidOperationException(const InvalidOperationException& e) : Exception(e) { }
    InvalidOperationException& operator= (const InvalidOperationException& e)
    {
        Exception::operator= (e);
        return *this;
    }
};
}
#endif // EXCEPTION_H
Exception.cpp
#include "Exception.h"
#include <cstring>
#include <cstdlib>
namespace StLib
{
void Exception::init(const char* message, const char* file, int line)
{
    /* message指向的字符串有可能在栈上,有可能在堆空间,还有可能在全局数据区
     * strdup()将字符串复制一份到堆空间中
     * file:发生异常的文件名
     * line:发生异常的行号
     * m_location的长度加2,一个给":",一个给"\0"
     */
    m_message = strdup(message);
    if( file != NULL )
    {
        char sl[16] = {0};
        itoa(line, sl, 10);
        m_location = static_cast<char*>(malloc(strlen(file) + strlen(sl) + 2));
        if( m_location != NULL )
        {
            m_location = strcpy(m_location, file);
            m_location = strcat(m_location, ":");
            m_location = strcat(m_location, sl);
        }
    }
    else
    {
        m_location = NULL;
    }
}
Exception::Exception(const char *message)
{
    init(message, NULL, 0);
}
Exception::Exception(const char* file, int line)
{
    init(NULL, file, line);
}
Exception::Exception(const char* message, const char* file, int line)
{
    init(message, file, line);
}
Exception::Exception(const Exception& e)
{
    m_message = strdup(e.m_message);
    m_location = strdup(e.m_location);
}
Exception &Exception::operator= (const Exception& e)
{
    if( this != &e )
    {
        free(m_message);
        free(m_location);
        m_message = strdup(e.m_message);
        m_location = strdup(e.m_location);
    }
    return *this;
}
const char* Exception::message() const
{
    return m_message;
}
const char* Exception::location() const
{
    return m_location;
}
Exception::~Exception()
{
    free(m_message);
    free(m_location);
}
}
StLib 的开发方式和注意事项:
第一阶段学习总结:
标签:idp 运行 示例 tor col 注意事项 namespace 错误 opera
原文地址:https://www.cnblogs.com/PyLearn/p/10109785.html