最近写过一个连锁酒店预订的一个小程序。和本文相关的部分代码摘录下来说明本主题内容 。
如果连锁酒店系统是存储各个酒店的指针来管理的,那么我们一般都是希望new出一个酒店并且添加到连锁系统的酒店对象指针的容器中(本文中的容器是map)。那么你是否能保证添加的指针一定是在堆上申请的呢?似乎这不是连锁系统自身可以控制的。那么如果传入的是栈指针,而在连锁系统对象析构时,把它存储的酒店对象指针当成堆指针delete的时候,我们的系统一定就崩溃了。
因此,如果你不能严格限制糟糕的程序员给你传入栈指针,那么你可以判断他传入指针的类型,来灵活应对。
对于编写库函数的同学,这一点需要特别注意,有时候我们往往无法控制程序员传入的数据类型,所以你不能假设他一定是按照你设想的方式和类型处理,我们能做的是尽可能的屏蔽或者处理这样的情况。
实例,请看代码(代码并不完整,仅仅为了说明本问题),注意红色字体的函数。
HotelManagement MiamiHotels;
//Hotel price according rate
HotelRate rate3(110.0, 90.0, 80.0, 80.0);
HotelRate rate4(160.0, 60.0, 110.0, 50.0);
HotelRate rate5(220.0, 150.0, 100.0, 40.0);
Hotel* pLakewood =newHotel("Lakewood", "Miami", 100, rate3);
Hotel* pBridgewood =newHotel("Bridgewood", "Miami", 100, rate4);
Hotel* pRidgewood =newHotel("Ridgewood", "Miami", 100, rate5);
MiamiHotels.addHotelToManage(pLakewood);
MiamiHotels.addHotelToManage(pBridgewood);
MiamiHotels.addHotelToManage(pRidgewood);
/*
//-----------------------------------------
// Test allocate the hotel object on stack
//-----------------------------------------
HotelLakewood("Lakewood", "Miami", 100, rate3);
Hotel Bridgewood("Bridgewood", "Miami", 100, rate4);
Hotel Ridgewood("Ridgewood", "Miami", 100, rate5);
MiamiHotels.addHotelToManage(&Lakewood);
MiamiHotels.addHotelToManage(&Bridgewood);
MiamiHotels.addHotelToManage(&Ridgewood);
*/
#define HOTEL_MANAGEMENT_H
#include <windows.h>
#include <iostream>
#include <map>
#include <string>
#include "Hotel.h"
using namespace std;
class HotelManagement
{
public:
typedef map<string,Hotel*>::iterator hotels_iter;
~HotelManagement();
void addHotelToManage(Hotel* pHotel);
bool isHotelMapEmpty();
bool findThecheapestHotel(int weekdays, int weekends, bool isRewardsCustomer, string& hotelName);
boolisObjectOnStack(Hotel* pHotel);
private:
map<string, Hotel*> _HotelsMap;
};
#endif
#include "HotelManagement.h"
bool HotelManagement::isObjectOnStack(Hotel* pHotel)
{
int stackValue = 0;
MEMORY_BASIC_INFORMATION mi = {0};
DWORD dwRet = VirtualQuery(&stackValue, &mi, sizeof(mi));
if(dwRet > 0)
{
return pHotel >= mi.BaseAddress
&& (DWORD)pHotel < (DWORD)mi.BaseAddress + mi.RegionSize;
}
return false;
}
HotelManagement::~HotelManagement()
{
hotels_iter iter;
for(iter = this->_HotelsMap.begin(); iter != this->_HotelsMap.end(); iter++)
{
if(isObjectOnStack(iter->second))
{
continue;
}
if(iter->second != NULL)
{
Hotel* temp = iter->second;
iter->second = NULL;
delete temp;
}
}
this->_HotelsMap.clear();
}
void HotelManagement::addHotelToManage(Hotel* pHotel)
{
_HotelsMap.insert(std::make_pair(pHotel->getHotelName(), pHotel));
}
分享到:
相关推荐
其中,构造函数在定义对象时被调用,析构函数在对象释放时被调用。如果用户没有提供构造函数和析构函数,系统将提供默认的构造函数和析构函数。 1.构造函数 构造函数是一个与类同名的方法,可以没有参数,有一个参数...
虚析构函数示例 c++析构函数是否是虚函数时的差别,敬请留意
析构函数 finalizer destructor 整理的关于析构函数的描述以及介绍
我们知道,用C++开发的时候,用来做基类的类的析构函数一般都是虚函数。可是,为什么要这样做呢?下面用一个小例子来说明:
关于析构函数和临时对象的问题,学习C++的朋友可以好好看看,不错
简单示例如何使用析构函数 包括析构函数的位置 作用方法等
当析构函数遇到多线程C++中线程安全的对象回调.pdf
描述了C++析构函数调用时间及分配对象堆与栈区别,一个理清C++析构函数和默认系统析构函数,C++堆栈分配的原则。
不能在结构中定义析构函数。只能对类使用析构函数。 一个类只能有一个析构函数。 无法继承或重载析构函数。 无法调用析构函数。它们是被自动调用的。 析构函数既没有修饰符,也没有参数。 例如,下面是类 Car 的析构...
深析C++析构函数,C++中析构函数是相当重要一个知识点,也是个难点。文档对析构函数了部分分析,可能不怎么全,但一点深入,相互学习呵呵
C++中基类的析构函数为什么要用virtual虚析构函数.pdf
析构函数(Destructors),是对象的成员函数,没有返回值也没有参数,且一个类只有一个析构函数,当对象被销毁的时候调用,被销毁通常有这么几个情况。 函数执行结束 程序执行结束 程序块包含的局部变量 delete...
C++中的构造函数、析构函数剖析 在C+ + 中, 构造函数是一个在构件对象的时 候调用的特殊的函数, 其目的是对对象进行初始 化工作, 从而使对象被使用之前可以处于一种合 理的状态。析构函数是在撤消对象时, 收回对象 ...
这是陈硕在 2009 年上海 C++ 技术大会演讲《当析构函数遇到多线程》的 PPT 投影片,可自由用于个人学习,其他使用需得到作者许可。 简介:编写线程安全的类不是难事,用同步原语保护内部状态即可。但是对象的生与死...
面向对象程序设计,即C++语言,类。析构函数,文件里面有详细的注释。
c++ 练习 析构函数 例子 初级,书上的一个例子
实验_构造函数与析构函数.doc实验_构造函数与析构函数.doc实验_构造函数与析构函数.doc
c#构造函数与析构函数.doc
delphi析构函数的使用,以及窗体的继承,多态。
详细解释了为什么析构函数可以是虚函数,而构造函数不能是虚函数