目录:
三、operator new 和 operator delete 函数的重载版本
| 例:两个函数的用法 |
|---|
| 例:只能创建栈对象的类 |
|---|
| 例:只能创建堆对象的类 |
|---|
| A. 对象销毁和调用析构函数等价吗? | A. 栈对象创建时需要哪些条件? |
|---|
一、new表达式工作步骤
使用new表达式时发生的三个步骤:
- 调用 名为
operator new的标准库函数,分配 足够大的原始的未类型化的内存,以 保存 指定类型的一个对象 - 运行 该类型的一个构造函数初始化对象
- 返回 指向新分配并构造的构造函数对象的指针
二、delete表达式工作步骤
使用delete表达式时发生的两个步骤:
- 调用 析构函数,回收 对象中数据成员 所申请的资源
- 调用 名为
operator delete的标准库函数释放 该对象 所用的内存
三、operator new 和 operator delete 函数的重载版本
以下是两个函数的形式:
//operator new库函数
void * operator new(size_t);
void * operator new[](size_t);
//operator delete库函数
void operator delete(void *);
void operator delete[](void *);
两个函数的用法:
class Student
{
public:
Student(int id, const char * name)
: _id(id)
, _name(new char[strlen(name) + 1]())
{
strcpy(_name, name);
cout << "Student()" << endl;
}
~Student()
{
delete [] _name;
cout << "~Student()" << endl;
}
void * operator new(size_t sz)
{
void * ret = malloc(sz);
return ret;
}
void operator delete(void * pointer)
{
free(pointer);
}
void print() const
{
cout << "id:" << _id << endl
<< "name:" << _name << endl;
}
private:
int _id;
char * _name;
};
int main(void)
{
Student * stu = new Student(100, "Jackie");
stu->print();
delete stu;
return 0;
}
四、要求一个类只能创建栈对象
如果要求一个类只能创建栈对象,其意思是在创建出栈对象的同时,不能创建堆对象。以Student类型 而言:
void test0()
{
Student s1(101, "John");//ok
Student * stu = new Student(101, "Mark");//error
}
要达到以上的效果,只需要 将operator new放入Student类的private区域。
例:只能创建栈对象的类
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
using std::cout;
using std::endl;
class Student
{
public:
Student(int id, const char *name)
: _id(id)
, _name(new char[strlen(name) + 1]())
{
cout << "Student()" << endl;
strcpy(_name, name);
}
void print() const
{
cout << "id : " << _id << endl
<< "name : " << _name << endl;
}
private:
void *operator new(size_t sz)
{
cout << "new()" << endl;
void *pret = malloc(sz);
return pret;
}
void operator delete(void *pointer)
{
cout << "delete()" << endl;
free(pointer);
}
public:
~Student()
{
cout << "~Student()" << endl;
if(_name)
{
delete [] _name;
_name = nullptr;
}
}
private:
int _id;
char *_name;
};
int main(int argc, char **argv)
{
Student stu(56, "Janell");//栈对象
stu.print();
// Student *pstu = new Student(12, "xiaoming");
return 0;
}
五、要求一个类只能创建堆对象
如果要求一个类只能创建堆对象,其意思是在创建出堆对象的同时,不能创建栈对象。以Student类型 而言,
void test1()
{
Student s1(101, "John");//error
Student * stu = new Student(101, "Mark");//ok
}
要达到以上的效果,只需要 将Student类的析构函数放入private区域。
例:只能创建堆对象的类
将析构函数放入private区域,为了清理,可以添加函数 destory() ,函数 destory() 执行 delete this; ,删除对象本身,包括数据成员的堆空间(析构函数)和对象本身堆空间(delete 函数重载)
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
using std::cout;
using std::endl;
class Student
{
public:
Student(int id, const char *name)
: _id(id)
, _name(new char[strlen(name) + 1]())
{
cout << "Student()" << endl;
strcpy(_name, name);
}
void print() const
{
cout << "id : " << _id << endl
<< "name : " << _name << endl;
}
void *operator new(size_t sz)
{
cout << "void *operator new(size_t)" << endl;
void *pret = malloc(sz);
return pret;
}
void operator delete(void *pointer)
{
cout << "void operator delete(void *)" << endl;
free(pointer);
}
void destroy()
{
//删除对象本身
delete this;
}
private:
~Student()
{
cout << "~Student()" << endl;
if(_name)
{
delete [] _name;
_name = nullptr;
}
}
private:
int _id;
char *_name;
};
int main(int argc, char **argv)
{
//Student stu(56, "xiaohong"); //error
Student *pstu = new Student(12, "xiaoming");
pstu->print();
pstu->destroy();
return 0;
}
六、注意问题
A. 对象销毁和调用析构函数等价吗?
Q: 不等价,析构函数是对象销毁的其中一步,对象销毁既要 调用析构函数回收对象中数据成员所申请的资源 等,又要 释放该对象所用的内存(彻底销毁对象)
假如将之前例子中的 new / delete 函数重载放到类外,创建回收对象的堆空间,以及对象成员申请释放的堆空间将会调用两次 new / delete 函数;
而将 new / delete 函数重载放到类内,将只有一次(构造 / 析构函数)。
A. 栈对象创建时需要哪些条件?
Q: 构造函数和析构函数都为非私有
本文深入探讨了C++中new和delete表达式的工作原理,包括内存分配与回收的步骤,operatornew和operatordelete的重载,以及如何通过修改类定义来限制对象的创建方式,仅允许创建栈对象或堆对象。

1万+

被折叠的 条评论
为什么被折叠?



