c++删除/析构函数安全调用
C++ delete/destructor safe call
我有一个"扭曲"的问题…假设有一个像
这样的类class MyClass {
public:
MyClass();
~MyClass();
MyClass& operator=(const MyClass& obj);
private:
int* mem;
};
基本上,MyClass
以某种方式初始化mem
(通过new
调用),~MyClass()
用delete
操作符释放mem
。再假设操作符=
重载了代码
MyClass& operator=(const MyClass& obj) {
if(this != &obj) {
//allocate memory of "this" with the "new" operator and copy "obj" data;
}
return *this;
}
我的问题基本上如下…使用以下语句序列
//statement 1 for short
MyClass my_obj = some_obj_of_MyClass;
我猜一切都很好,因为操作符=
分配内存并复制数据,但是下面的
//statement 2 for short
MyClass obj; //allocate memory for "mem"
obj = some_obj_of_MyClass;
如果认为这是不正确的实现,我建议,因为我不删除内存分配的早期。我可以在赋值操作符块中调用析构函数,但在这种情况下,语句1可能不安全。
那么实现一切的安全方式是什么呢?我猜这里的问题可能是理解何时调用析构函数或如何正确实现它。
您的代码违反了第三条规则:
- 拷贝构造函数
- 复制赋值操作符
- 析构函数
它应该提供所有这三个。因为,如果省略了其中的任何一个,就有可能构造出发生不良事件的用例。例如,与直觉相反,语句
MyClass my_obj = some_obj_of_MyClass;
不调用赋值操作符。它调用您没有提供的复制构造函数。因此,使用默认的复制构造函数,它只是复制指针。一旦my_obj
或some_obj_of_MyClass
被销毁,另一个将有一个指针指向被删除的内存区域。
MyClass obj;
obj = some_obj_of_MyClass;
将首先默认构造obj
,然后对其调用赋值操作符。赋值操作符必须在obj
的每一种可能状态下都能正确地工作(即它不能泄漏内存或双删除内存)。也就是说,如果分配了obj.mem
,则赋值操作符必须重用该内存或释放它(可能用新的分配替换它)。如果obj.mem
可以是空指针,那么赋值操作符必须包含对这种特殊情况的特殊处理。
所以,你的选择基本上是,你是否想让mem
指针成为一个空指针,如果你不允许,你的默认构造函数必须分配一个虚拟的内存区域,可以通过赋值操作符释放。
您还可以通过删除未实现的函数来绕过三规则。你的类可以这样声明:
class MyClass {
public:
MyClass();
MyClass(const MyClass&) = delete;
MyClass& operator=(const MyClass& obj);
~MyClass();
private:
int* mem;
};
这将禁止语句
MyClass my_obj = some_obj_of_MyClass;
强制用户代码使用更详细的
MyClass obj;
obj = some_obj_of_MyClass;
,但这使得MyClass
的实现更简单。
相关文章:
- 以线程安全的方式调用"QQuickPaintedItem::updateImage(const QImage&image)"(no QThread)
- 线程调用的函数对对象删除是否安全?
- 由并发无序映射查找线程调用的函数是否安全?
- 当我在C++中调用 struce 的只读静态成员时,线程是否安全
- 同时调用 ASIO 对象的 API 是否安全?
- 对于琐碎的对象,在"this"上调用新放置是否安全?
- 使用范围解析运算符时,在构造函数中调用虚拟方法是否安全?
- 混合延迟 dll 加载和手动调用 LoadLibraryA 是否安全?
- 从 WindowsAPI 调用 NetLocalGroupAddMembers 时,安全 ID 结构无效错误
- 在移出向量上调用 size() 方法是否安全?
- 将整数添加到数组值而无需调用它的最安全方法
- 在 c++ 中,所有 system() 调用都存在安全风险吗?
- 调用不访问已删除对象中的任何类成员的类方法是否安全
- 从不同线程调用mpi_init是安全的吗?
- 静态初始化不安全调用的线程安全
- 在Visual C 中找到调用函数地址(安全)
- 从 std::d eque 线程对 emplace_back() 和运算符 []() 的并发调用是否安全?
- Openssl 线程安全回调函数注册,包括直接调用和间接调用
- c++删除/析构函数安全调用
- 正在使用空weak_ptr作为参数安全调用map::count