more effective C++设计模式 要求(或禁止)对象产生于heap中
2017-09-18 14:35
471 查看
要求(或)禁止对象产生于heap中
有时候我们想让某种对象具有自杀的能力,所以我们必须要求对象存在堆中,以便我们调用delete this.有的时候堆空间非常宝贵,并且我们需要保证不发生内存泄露所以我们要对象全为栈对象,必须禁止对象产生于堆中。
要求对象产生于堆中
一种典型的手法是把析构函数声明为protected,然后给类一个伪构造函数destroy来调用delete this.下面我们来看例子:
class UPNumber
{
public:
UPNumber();
UPNumber(int initValue);
UPNumber(const UPNumber& rhs);
void destroy() { delete this; }
protected:
~UPNumber();
}这里注意我们析构函数声明为protected,以保证该类可以被继承(拥有private 构造函数以及析构函数的类 不能被继承),当我们以这种做法来实现的时候,其他的类如果想要该类作为其成员,只能存储器指针。
但是这里还是存在一些问题,如果我们有一个类继承了UPNumber,比如说是NonNegativeUPNumber 。然后我们定义了NonNegativeUPNumber n;此时派生类的基类部分是存在于栈之中的,所以我们严格要求对象产生于栈中不太合适。所以我们在返回去看我们之前提出的问题,我们想知道对象是否产生于堆中,或者我们想调用delete this.是时候重新重新审视我们的需求了。说到底我们可能的需求是判断一个指针的删除操作是否安全,并不是判断对象是否一定位于堆中。
位于堆中的对象不一定就能够被安全的删除,比如当作为一个类的成员变量的时候。
一个有效的办法就是继承一个class HeapTracked:
实现如下:
class HeapTracked
{
private:
typedef const void* RawAddress;
static list<RawAddress> address;//用于存储被operator new 分配的内存,需要我们注意的是,真的需要给这个类进行如此繁重的记录工作吗 慎重!
public:
class MissAddress{};//用于抛出异常
static void *operator new(size_t size);
static void*operator delete(size_t size);
virtual ~HeapTracked()=0;//为了调用dynamic_cast<const void*>
bool isHeaped() const;//调用dynamic_cats<void*>对this进行list查询
}
总结起来如果一个类不会被继承,那么让他只能产生于堆之中是非常好实现的(将析构函数声明为private),但是如果是可以被继承,并且严格要求被产生于堆之中,那么基本很难实现。那么要判断一个类的对象能不能被delete,一个好的实现就是让他继承HeapTracked,但是这也带来复杂的记录工作,需要慎
4000
重考虑是否需要这种实现。
禁止对象产生于heap之中
我们只需要在类中把声明private的void* operator new(size_t size) 函数.
有时候我们想让某种对象具有自杀的能力,所以我们必须要求对象存在堆中,以便我们调用delete this.有的时候堆空间非常宝贵,并且我们需要保证不发生内存泄露所以我们要对象全为栈对象,必须禁止对象产生于堆中。
要求对象产生于堆中
一种典型的手法是把析构函数声明为protected,然后给类一个伪构造函数destroy来调用delete this.下面我们来看例子:
class UPNumber
{
public:
UPNumber();
UPNumber(int initValue);
UPNumber(const UPNumber& rhs);
void destroy() { delete this; }
protected:
~UPNumber();
}这里注意我们析构函数声明为protected,以保证该类可以被继承(拥有private 构造函数以及析构函数的类 不能被继承),当我们以这种做法来实现的时候,其他的类如果想要该类作为其成员,只能存储器指针。
但是这里还是存在一些问题,如果我们有一个类继承了UPNumber,比如说是NonNegativeUPNumber 。然后我们定义了NonNegativeUPNumber n;此时派生类的基类部分是存在于栈之中的,所以我们严格要求对象产生于栈中不太合适。所以我们在返回去看我们之前提出的问题,我们想知道对象是否产生于堆中,或者我们想调用delete this.是时候重新重新审视我们的需求了。说到底我们可能的需求是判断一个指针的删除操作是否安全,并不是判断对象是否一定位于堆中。
位于堆中的对象不一定就能够被安全的删除,比如当作为一个类的成员变量的时候。
一个有效的办法就是继承一个class HeapTracked:
实现如下:
class HeapTracked
{
private:
typedef const void* RawAddress;
static list<RawAddress> address;//用于存储被operator new 分配的内存,需要我们注意的是,真的需要给这个类进行如此繁重的记录工作吗 慎重!
public:
class MissAddress{};//用于抛出异常
static void *operator new(size_t size);
static void*operator delete(size_t size);
virtual ~HeapTracked()=0;//为了调用dynamic_cast<const void*>
bool isHeaped() const;//调用dynamic_cats<void*>对this进行list查询
}
总结起来如果一个类不会被继承,那么让他只能产生于堆之中是非常好实现的(将析构函数声明为private),但是如果是可以被继承,并且严格要求被产生于堆之中,那么基本很难实现。那么要判断一个类的对象能不能被delete,一个好的实现就是让他继承HeapTracked,但是这也带来复杂的记录工作,需要慎
4000
重考虑是否需要这种实现。
禁止对象产生于heap之中
我们只需要在类中把声明private的void* operator new(size_t size) 函数.
相关文章推荐
- 《More Effective C++》学习心得(八) 要求(或禁止)对象产生于heap中
- More Effective C++(条款27:要求(或禁止)对象产生于heap之中)
- More Effective C++ 条款27 要求(禁止)对象产生与heap之中
- more effective C++设计模式限制对象产生
- More Effective C++ 阅读笔记(十三)--要求或禁止在堆中产生对象
- More Effective C++----(27)要求或禁止在堆中产生对象
- 《MORE EFFECTIVE C++》条款27 要求或者禁止对象分配在堆上
- C++中要求(或禁止)对象产生于heap中
- 条款27:要求/禁止对象产生于heap中
- More Effective C++ 条款26 限制某个class所能产生的对象数量
- 《More Effective C++》条款26:限制某个Class所能产生的对象数量
- More Effective C++(条款26:限制某个class所能产生的对象个数)
- 技术(3)—要求(或禁止)对象产生于heap之中
- More Effective C++----(26)限制某个类所能产生的对象数量
- 【more effective c++读书笔记】【第5章】技术(3)——要求(或禁止)对象产生于heap之中
- 【M27】要求或者禁止对象产生于heap之中
- 【more effective c++读书笔记】【第5章】技术(3)——要求(或禁止)对象产生于heap之中
- 条款二十七 要求或者禁止对象产生于heap中
- 13.如何做到要求或禁止在堆中产生你自定义的对象
- 要求或禁止在堆中产生对象