类只能在栈上创建
我们知道一个对象可在堆上创建或者栈上创建,c++中创建一个堆对象需要使用new运算符才可以,因为malloc不会调用构造和析构函数。因此想要达到该类只能在栈上创建,需要屏蔽new/delete运算符。
我们将new/delete设置为private属性,我们在类外就无法调用该运算符,也就达到了这个类只能在栈上创建
的效果。
//如何设计类只能建立在栈
class CClassInstanceStack
{
public:
CClassInstanceStack()
{
std::cout << "call construct function\n";
}
~CClassInstanceStack()
{
std::cout << "call destruction function\n";
}
void print_log()
{
std::cout << "call print log\n";
}
/**/
//new 运算符是private,外部禁止调用 因此该类只能在栈上创建
//重载了new运算符也需要重载delete运算符
private:
void* operator new(std::size_t count){}
void* operator new[](std::size_t count){}
void operator delete[]( void* ptr ){}
void operator delete( void* ptr ){}
};
/*类的使用*/
//无法访问 operate new或者new[]运算符
//build error
CClassInstanceStack* parrStack = new CClassInstanceStack[10];
//build error
CClassInstanceStack* pStack = new CClassInstanceStack;
//build ok
CClassInstanceStack stack;
stack.print_log();
类只能在堆上创建
同理,一个类对象只能在堆上创建,那么对外只能提供new运算符接口,而构造函数或者析构函数至少有一个需要时私有的。因为我们在栈上创建对象时,需要调用构造函数,析构时会调用析构函数,屏蔽其中之一,栈上创建对象,编译器就能告警和编译异常。这类设计如下:
/*
想要达到只能在堆上创建对象,其设计要求如下:
1.该类的构造函数或者析构函数至少有一个是private属性
2.提供一个创建对象接口,用于类内部创建堆对象
3.提供堆对象销毁函数,这个非必须,需要看析构是否public属性
*/
class COnlyHeap
{
private:
COnlyHeap():m_data(0){}
~COnlyHeap(){}
public:
static COnlyHeap* CreateObj()
{
return new (std::nothrow) COnlyHeap;
}
static void DestroyObj(COnlyHeap* &pInstance)
{
if (NULL != pInstance)
{
delete pInstance;
pInstance = NULL;
}
}
int m_data;
};
//类的使用
COnlyHeap OnlyHeap;//build error
COnlyHeap* pOnlyHeap = COnlyHeap::CreateObj();
if (NULL != pOnlyHeap)
{
pOnlyHeap->m_data = 10;
}
//需要手动释放对象,否则内存泄漏,不易维护
if (NULL != pOnlyHeap)
{
COnlyHeap::DestroyObj(pOnlyHeap);
}
类只能一个对象
对于一个类只能创建一个对象,对应的就是设计模式当中的单例模式,单例模式关键点有以下:
- 构造函数和析构函数为private属性
- 全局唯一的访问点为public属性
- 为了使用方便,增加一个GC辅助类,用于释放资源。
这个类设计如下:
//类只能在堆上实例化
//1、如何设计类只能建立在堆上&单例模式只有一个模式
class CClassInstanceHeap
{
private:
CClassInstanceHeap(){}
~CClassInstanceHeap(){}
public:
static CClassInstanceHeap* GetInstance()
{
return m_pIns;
}
void print_log()
{
std::cout << "print log by instance\n";
}
private:
// 是CClassInstanceHeap的辅助类,用于资源的释放
class GC
{
public:
GC()
{
std::cout << "gc construct \n";
}
~GC()
{
//析构时释放资源
std::cout << "gc delete instance \n";
if (m_pIns != NULL)
{
delete m_pIns;
m_pIns = NULL;
}
}
};
private:
static CClassInstanceHeap* m_pIns;
static GC m_gc;
};
//类外初始化静态变量
//懒汉式 避免了多线程竞争问题
//对象的初始化
CClassInstanceHeap* CClassInstanceHeap::m_pIns = new CClassInstanceHeap;
CClassInstanceHeap::GC CClassInstanceHeap::m_gc;
//main函数
//具有垃圾回收功能
CClassInstanceHeap::GetInstance()->print_log();
//运行结果
gc construct
print log by instance
gc delete instance
以上就是类设计当中,比较特殊的三种情况了,欢迎大家一起交流!