一道C++笔试题:设计一个只能在堆内存上实例化的类和一个只能在栈内存上实例化的类
只能在堆内存上实例化的类:将析构函数定义为private,在栈上不能自动调用析构函数,只能手动调用。也可以将构造函数定义为private,但这样需要手动写一个函数实现对象的构造。
using namespace std;
//只能在堆内存上实例化的类
class CHeapOnly
{
public:
CHeapOnly()
{
cout << "Constructor of CHeapOnly!" << endl;
}
void Destroy() const
{
delete this;
}
private:
~CHeapOnly()
{
cout << "Destructor of CHeapOnly!" << endl;
}
};
{
public:
CStackOnly()
{
cout << "Constructor of CStackOnly!" << endl;
}
~CStackOnly()
{
cout << "Destrucotr of CStackOnly!" << endl;
}
private:
void* operator new(size_t size)
{
}
void operator delete(void * ptr)
{
}
};
int main()
{
//use of CHeapOnly
CHeapOnly* pHeap = new CHeapOnly;
pHeap->Destroy();
//error use of CHeapOnly
//CHeapOnly objHeap;
//use of CStackOnly
CStackOnly objStack;
//error use of CStackOnly
//CStackOnly* pStack = new CStackOnly;
return 0;
}
下面一个类也只能在堆内存上生成,将构造函数和析构函数都定义为private,但是可以通过类的static函数创建对象,不过这个对象是不能被继承的。
#include <iostream>
using namespace std;
//只能在堆内存上实例化的类
class FinalClass
{
public :
static FinalClass* GetInstance()
{
cout<<"Constructor of the class"<<endl;
return new FinalClass;
}
static void DeleteInstance(FinalClass* pInstance)
{
cout<<"Destructor of the class"<<endl;
delete pInstance;
pInstance = 0;
}
private :
FinalClass() {}
~FinalClass() {}
};
int main()
{
//use of CHeapOnly
FinalClass* fc = FinalClass::GetInstance();
FinalClass::DeleteInstance(fc);
return 0;
}
只能在堆内存上实例化的类:将析构函数定义为private,在栈上不能自动调用析构函数,只能手动调用。也可以将构造函数定义为private,但这样需要手动写一个函数实现对象的构造。
只能在栈内存上实例化的类:将函数operator new和operator delete定义为private,这样使用new操作符创建对象时候,无法调用operator new,delete销毁对象也无法调用operator delete。
using namespace std;
//只能在堆内存上实例化的类
class CHeapOnly
{
public:
CHeapOnly()
{
cout << "Constructor of CHeapOnly!" << endl;
}
void Destroy() const
{
delete this;
}
private:
~CHeapOnly()
{
cout << "Destructor of CHeapOnly!" << endl;
}
};
//只能在栈内存上实例化的类,就是不能使用new来构造类,把operator new私有化
operator new 函数用来为对象分配原始内存。New 操作符的第一步调用的就是operator new 。你可以重载这个函数。它的原型如下:
Void* operator new(size_t size);
函数的返回值是void*, 因为这个函数返回的是指针。这个指针指向原生的,为初始化的内存。其语义就像malloc 。实际上它内部调用的就是malloc 。参数size 指定待分配的内存大小。你可以在重载的时候加上额外的参数,但是第一个参数类型必须是size_t.
{
public:
CStackOnly()
{
cout << "Constructor of CStackOnly!" << endl;
}
~CStackOnly()
{
cout << "Destrucotr of CStackOnly!" << endl;
}
private:
void* operator new(size_t size)
{
}
void operator delete(void * ptr)
{
}
};
int main()
{
//use of CHeapOnly
CHeapOnly* pHeap = new CHeapOnly;
pHeap->Destroy();
//error use of CHeapOnly
//CHeapOnly objHeap;
//use of CStackOnly
CStackOnly objStack;
//error use of CStackOnly
//CStackOnly* pStack = new CStackOnly;
return 0;
}
下面一个类也只能在堆内存上生成,将构造函数和析构函数都定义为private,但是可以通过类的static函数创建对象,不过这个对象是不能被继承的。
#include <iostream>
using namespace std;
//只能在堆内存上实例化的类
class FinalClass
{
public :
static FinalClass* GetInstance()
{
cout<<"Constructor of the class"<<endl;
return new FinalClass;
}
static void DeleteInstance(FinalClass* pInstance)
{
cout<<"Destructor of the class"<<endl;
delete pInstance;
pInstance = 0;
}
private :
FinalClass() {}
~FinalClass() {}
};
int main()
{
//use of CHeapOnly
FinalClass* fc = FinalClass::GetInstance();
FinalClass::DeleteInstance(fc);
return 0;
}