设计一个类,只在堆上创建对象
class HeapOnly
{
public:
static HeapOnly* GetHeapObj()
{
return new HeapOnly;
}
private:
//构造函数私有
HeapOnly()
{}
//C++98:拷贝构造函数只声明不实现,并且声明成私有的
HeapOnly(const HeapOnly&);
//C++11:拷贝构造函数delete
HeapOnly(const HeapOnly&) = delete;
};
int main()
{
HeapOnly* obj = HeapOnly::GetHeapObj();//产生堆上的对象
}
思路分析:
- 构造函数要定义为私有的,因为调用构造函数产生的对象都在栈上
- 但是构造函数私有之后,对象new不出来了,因此要在类里面提供接口GetHeapObj,然后直接返回new出来的对象,这样产生的对象就在堆上
- 但是要调用这个GetHeapObj接口的话只有通过对象才能调用,而我们不能调用构造产生对象,那么应该怎么办呢?那就是把这个接口定义为静态的,静态的成员函数不需要对象也可以调用。
- 那又出现一个问题,如果我们调用这个GetHeapObj接口然后成功的产生了一个堆上的对象,如果再调用拷贝构造函数又会产生栈上的对象。所以我们要把拷贝构造函数也封杀掉,那如果是在C++98中我们就把拷贝构造函数只声明不实现就可以了,如果是在C++11中我们可以使用delete将这个函数删除,像这样
HeapOnly(const HeapOnly&) = delete;
也是可以的。 - 把构造函数封杀了,因此全局的变量也不可以被定义,所以就只能在堆上创建对象了
设计一个类,只在栈上创建对象
方法一:
class StackOnly
{
public:
static StackOnly GetStackObj()
{
return StackOnly();
}
private:
StackOnly()
{}
};
int main()
{
StackOnly obj = StackOnly::GetStackObj();
}
思路分析:
- 构造函数要定义成私有的,因为防止new创建出堆上的对象
- 在类里提供GetStackObj接口,直接返回栈上的对象
- 同时把GetStackObj接口设置为静态的,不用对象也可以调用
- 因为这样把构造函数封杀了,因此全局的变量也不可以被定义,所以就只能在栈上创建对象了
方法二(C++98)
class StackOnly
{
public:
static StackOnly GetStackObj()
{
return StackOnly();
}
private:
void* operator new(size_t size);
void operator delete(void* p);
};
int main()
{
StackOnly obj = StackOnly::GetStackObj();
}
思路分析:
这里是针对C++98,可以把operator new和operator delete放在私有里,这样就不能创建出堆上的对象了,但是这里会有一个bug就是全局的对象可以被创建出来。
方法三(C++11)
class StackOnly
{
public:
static StackOnly GetStackObj()
{
return StackOnly();
}
void* operator new(size_t size) = delete;
void operator delete(void* p) = delete;
};
int main()
{
StackOnly obj = StackOnly::GetStackObj();
}
思路分析:
这里是针对C++11,可以直接把operator new和operator delete用delete删除,这样就不会创建出堆上的对象,但是这里和方法二一样有一个bug就是全局的对象可以被创建出来。