#include<iostream>
class Base1
{
public:
virtual ~Base1(){}
};
class Base2
{
public:
virtual void f()=0;
// virtual ~Base2(){};
};
class Derive:public Base1,public Base2
{
public:
void f(){std::cout<<"f\n";}
~Derive(){std::cout<<"Derive dtor\n";}
};
void func(Base2* p)
{
p->f();
}
int main(int , char**)
{
Derive *p = new Derive;
Base1 *pb1=p;
Base2 *pb2=p;
func(p);
delete p;
//delete pb1;
//delete pb2;
}
此代码通过修改base2的虚dtor 和 main中的delete pb2 ,会导致crash。
所谓的delete分为两步,runtime在遇到一个delete的时候,理论上会调用一个叫做delete
operator的东西,这个东西会先调用dtor,然后调用operator delete来释放内存。我们能够重载的是operator
delete,而delete operator是无法重载的。对于operator
delete来说,它接受一个void*为参数,它只负责释放内存。那么,按照你的layout,pb1和d指向的内存地址肯定是不一样的,由于
Base1有大小,pb2会有一个偏移。因此,对于operator delete来说,如果你传给它pb2,它就直接over了。那么,delete operator怎么可以知道应该怎样传递正确地传递地址过去呢?这是因为,delete
operator有点类似于virtual的。要实现这个virtual特性的先决条件就是,你的dtor必须是virtual的。这就可以解释为什么你
把virtual注释了,就会over。
static void* operator new(size_t size){
void* p=::operator new(size);
std::cout<<"Base2 new: "<<std::hex<<p<<"\n";
return p;
}
static void operator delete(void* p){
std::cout<<"Base2 del: "<<std::hex<<p<<"\n";
::operator delete(p);
}
可以打印指针指向的内存,可以看到,pb1和pb2和p指向是不一样的。要注意程序走进哪个operator delete。相关资料详见
effective c++ 7
分享到:
相关推荐
### JS中的内部属性与delete操作符介绍 JavaScript(JS)是一种广泛使用的高级编程语言,它具备丰富的内部属性,以及特定的关键字和操作符来控制这些属性的行为。其中,`delete` 操作符是一个重要的组成部分,它...
JavaScript中的delete操作符是一种用于删除对象属性的运算符,其作用是移除对象的指定属性。然而,在实际应用中,delete操作符的行为可能会让人感到困惑,因为它在处理对象、数组以及变量时有着不同的特性。 首先,...
在C++中,`new`和`delete`操作符是用于动态内存管理的关键工具,而`new[]`和`delete[]`则是针对数组进行动态内存分配和释放的特殊形式。 `new`操作符: `new`操作符用于向系统申请一块内存空间。当使用`new`关键字...
主要介绍了Javascript中的delete操作符详细介绍,着重介绍了哪些情况可以使用delete操作符,以有delete操作符的返回值等问题,需要的朋友可以参考下
new、delete(new[]、delete[])操作符的重载需要注意: 1.重载的 new、delete(或者 new[]、delete[])操作符必须是类的静态成员函数(为什么必须是静态成员函数,这很好理解,因为 new 操作符被调用的时候,对象还...
1、实现上delete操作符会调用引擎内部的[[Delete]]方法 2、[[Delete]]在8.6.2里定义 3、删除的属性有个DontDelete的特性,如果有,delete时直接返回false 搜索“DontDelete”,会发现有很多,如下都不能delete 1, ...
但是,在使用布局new操作符分配内存时,我们不能直接使用delete操作符来释放内存。例如: delete pc1; // 错误的做法 这是因为布局new操作符并没有返回内存的地址,而是将对象创建在现有的内存块上。因此,我们...
JavaScript中的`delete`操作符主要用于从对象中删除属性,或者在某些旧的浏览器环境中尝试从数组中删除元素。然而,它的行为并不像C++中的`delete`,后者用于释放内存。在JavaScript中,`delete`不会直接影响到属性...
3. **某些操作符不能重载**:如`new`, `delete`, `::`, `sizeof`, `...`等,这些操作符不能被重载。 4. **防止滥用**:虽然可以重载几乎所有的操作符,但应谨慎行事,避免可能导致误解或混淆的操作符重载。 **操作...
- 标准库:C++标准库提供了广泛的功能,包括输入输出、字符串操作、数学运算、数据结构等。 - 性能:C++通常提供接近于C语言的性能,因为它允许直接访问内存地址和底层硬件。 - 跨平台:C++代码可以在多种操作系统和...
### C++关键字和操作符替代名 #### 概述 在C++编程语言中,关键字是具有特定含义的预定义标识符,它们被语言保留用于构成语法结构的关键部分。此外,C++还支持一系列操作符,包括算术、比较、逻辑等类型。为了提高...
本手册将详细阐述C++中操作符重载的相关规则、建议以及如何重载`operator new`。 **一、操作符重载规则** 1. **可重载的操作符** 包括基本的算术运算符(`+ - * / % ^ & | ~ !`),比较运算符(`< > <= >= == !=`...
本文主要讲解了如何在JavaScript中删除对象的某个属性,并通过实际案例详细解释了delete操作符的使用方法。在JavaScript中,delete操作符主要用于删除对象的属性。如果操作成功,delete会返回true,否则返回false。...
了解如何正确使用这两个操作符对于避免内存泄漏和其他内存相关的问题至关重要。 `new` 操作符主要有以下两种用法: 1. 分配单个变量的内存: ```cpp Type* var = new Type; ``` 这会为指定类型 `Type` 的一个...
**释放数组内存操作符** `delete[]` - **描述**: 释放数组的内存。 - **示例**: ```cpp delete[] array; // 释放数组的内存 ``` - **是否可重载**: 可重载。 - **结合性**: 右结合。 ##### 27. **类型转换操作...