C++:让一个类只能在堆/栈上创建对象
在C++中,类的对象创建有两种形式,一是静态创建,如A
a;另一种是动态创建,如A *p=new A;
静态创建一个类对象,是由编译器为对象在栈空间中分配内存。
动态创建对象,是使用new运算符将对象创建在堆空间中。
动态创建又分为两步:
operate new()函数在堆空间找到合适内存并分配
调用构造函数构造对象,初始化内存空间
operate new()
在说创建对象前,先聊一下operate new()的重载。
如果不想使用系统原始的内存分配方式时,可以自定义内存分配方式。
1 2 3 4 5 6 7 8 9 10 11 12 13
| void * operator new(size_t sz) { cout << "void * operator new(size_t)" << endl; void * p = malloc(sz); return p; }
void operator delete(void * p) { free(p); cout << "void operator delete(void*)" << endl; }
|
只能生成栈对象
new创建的对象会在栈空间,那么把new和delete放在private中,不允许调用即可
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| #include <string.h> #include <iostream> using namespace std;
class Student { public: Student(int id, const char * name) : _id(id) , _name(new char[strlen(name) + 1]()) { strcpy(_name, name); cout << "Student(int, const char *)" << endl; } ~Student() { delete [] _name; cout << "~String()" << endl; }
private: void * operator new(size_t sz); void operator delete(void * p); private: int _id; char * _name; }; int main(void) { Student student(1002, "Jackie"); student.print();
return 0; }
|
只能生成堆对象
类对象只能创建在堆上,即不能静态创建对象。
构造函数私有貌似能解决这个问题,想想上面说的new实际上两步,第二步要使用构造函数进行初始化,故并不可行。
这里很巧妙,把该类的析构函数私有化。因为如果静态创建对象,编译器在对象使用完后会自动调用析构函数释放空间,但是析构函数为私有的,导致编译器无法调用析构函数,所以如果析构函数是私有的,编译器不会在栈空间上为类分配内存
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| #include <string.h> #include <iostream> using namespace std;
class Student { public: Student(int id, const char * name) : _id(id) , _name(new char[strlen(name) + 1]()) { strcpy(_name, name); cout << "Student(int, const char *)" << endl; }
void destroy() { delete this; }
private: ~Student() { delete [] _name; cout << "~String()" << endl; }
private: int _id; char * _name; }; int main(void) { Student * pstu = new Student(1001, "Mary"); pstu->print(); pstu->destroy();
}
|
参考资料