如何定义一个只能在堆上创建对象的类?
首先我们要知道堆上和栈上存放的内容是什么?栈上面放的是形参和局部变量,对于堆,动态内存分配一般都是堆上的空间,比如malloc/calloc/realloc/free new/delete都是在分配堆上的空间。
那么我们现在只能在堆上创建对象,也就意味着不能在栈上创建对象,也就是说不能出现局部变量,也不能创建全局变量,那么应该怎么做呢?
1、那就是不能在类外使用构造函数创建对象,如果将构造函数都设为私有那么在堆上也不能创建对象了,所以我们要提供一个公有的成员函数来调用构造函数。在调用函数里使用 new 创建对象。
2、在实现这个成员函数时要考虑一个问题:在类外都不能创建对象了,那么如何去调用这个成员函数呢? 那么我们将这个公有的成员函数定义为静态的问题就迎刃而解了。因为类静态成员即可用类名::静态成员或者对象.静态成员来访问 。这样就可以调到那个成员函数来创建堆上的对象。
class HeapOnly
{
public:
//如果不定义为静态的,那么调用这个函数就要使用对象来调,可是这就是构造函数,之前是没有对象的,所以定义为静态函数就可以用HeapOnly::GetHeapObj()来调用。
static HeapOnly* GetHeapObj()
{
return new HeapOnly;
}
private:
HeapOnly() //1.如果只将构造函数设为私有的,那么虽然不能在栈上创建对象,
//在堆上也不能调用构造函数创建对象了。所以应该提供一个公有的成员函数来调构造
{}
//HeapOnly(const HeapOnly&); //c++98
HeapOnly(const HeapOnly&) = delete; //c++11
};
int main()
{
HeapOnly* pobj = HeapOnly::GetHeapObj(); //在堆上创建对象
return 0;
}
有心的大佬可以看见这里我将拷贝构造设为私有用的是c++11的方法,那么为什么不用c++98的方法呢?
这是因为c++98版本的写法有一点小瑕疵,那就是我可以通过在类外定义友元函数来调用这个私有的拷贝构造,这样同样是栈上的对象,用c++11的方法就不会出现这种问题,因为c++11这种写法相当于将拷贝构造函数变成了delete函数一样。所以不用考虑友元的情况。