C++杂谈之一二三-new

前言

  new这个关键字,贯穿于我们所有c++代码中,我们知道他是申请了一块内存给我们开发人员用,但是其中发生了什么?很多人都不得而知,本文就让我们一起研究一下new。

new的作用

  大家在定义一个对象或者指针的时候,会不会有这么的疑问?

ClassA a;
ClassA *b = new ClassA();//这两种方式有什么区别

  首先对象和指针的区别,在前文研究指针的时候,我们已经了解过,具体可以参照博客:c++基本语法之一二三(1)-初识指针

  这部分就不再赘述,但是为什么不能写成这个方式呢?

ClassA a;
ClassA *b = &a;//这两种方式有什么区别

  这种方式定义的b指针和上面定义的b指针有什么区别吗?
  答案是:第一种b指针指向对象内存是存放在堆内存中,第二种b指向了a的内存首地址,而a的内存是存放在栈中的,而堆栈之间的具体区别,我准备专门在另一篇研究c++内存分布的文章中细细研究~,而现在我们只需要知道堆内存是由开发人员自己控制的一部分内存,如果开发人员申请之后不自己释放的话,那么这块内存会一直被占用,这也就是内存泄漏问题的最常见的原因,那么栈内存会在超出变量作用域的时候由编译器自动释放。
  而new关键字的作用就是申请一块堆内存,然后返回这块堆内存的首地址。
  new可以称为new operator,也就是new,其中new可以分为两部分,operator new和placement new,下面我们分别研究一下。

operator new

  operator new的作用是申请一块堆内存,但也仅仅是申请一块堆内存,并没有构造对象的过程,来看代码

#pragma once
#include <iostream>

class base
{
public:
	int privateValue;
public:
	void* operator new(size_t _Size)
	{
		std::cout << "此时operator new被调用" << std::endl;
		return (void*)malloc(_Size);
	}
};

然后,我们new这么一个对象

#include <iostream>

int main()
{
	base* ptr = nullptr;
	ptr = new base();
	delete ptr;
}

  此时,我们看一下输出结果:
在这里插入图片描述
  我们发现,编译器调用了我们类中重写的operator new函数,并没有用全局的operator new函数,这就引出我们的一个结论:若在new一个类对象时,类中如果重写了operator new,则用类自定义的,若没有,则用全局的。

placement new

  使用operator new申请到一块堆内存之后,我们还需要做什么事呢?是不是需要将我们的对象在这块内存中分布起来,也就是我们买了一套房子,现在我们的住户需要搬进去了,我们改一下.h的代码,来看:

#pragma once
#include <iostream>

class base
{
public:
	int privateValue;
public:
	void* operator new(size_t _Size)
	{
		std::cout << "此时operator new被调用" << std::endl;
		return ::operator new(_Size);
	}

	void* operator new(size_t _Size,void *ptr)
	{
		std::cout << "此时placement new被调用" << std::endl;
		return ::new(ptr)base();
	}
};
int main()
{
	int a;
	base* ptr = new((void *)&a) base;
}

  来看结果:
在这里插入图片描述

  此时调用了类重写的placement new函数,而这个函数实际上也就是operator new的另一个重载版本,函数原型为:void* operator new(size_t _Size,void* ptr) ;这个函数的作用是在ptr指向的内存中构造对象。但是此时构造函数却被调用了两次,这个问题比较奇怪~
  想一想,这可以在我们的实际开发中有什么作用?我们在现有的内存位置中构造对象,能够减少程序对内存的申请,从而减少整个程序的资源占用。

小结

1.new可以称为new operator,也就是new,其中new可以分为两部分,operator new和placement new。
2.operator new的作用是申请一块堆内存,并返回内存的首地址。
3.placement new的作用是在指定的内存位置中构造对象。
4.其他:operator new对应的有operator delete,placement new 对应placement delete,其中delete操作符的调用顺序与new相反,也就是先调用placement delete,然后再调用operator delete,其中placement delete仅仅只调用析构函数,而不对内存有操作,operator delete会释放所对应的内存块,这里不多做解释。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值