当前位置:网站首页>The underlying principles and templates of new and delete
The underlying principles and templates of new and delete
2022-07-08 00:09:00 【__ cplusplus】
Main contents of this paper :
- new and delete The underlying principle of
- What is a template
- How to use templates
- Can a template be declared and defined in two files ?
new and delete The underlying principle of
We talked about new and delete Use , And the C In language malloc and free The difference between . however ,new and delete The processing of built-in types is different from malloc and free Very similar . Then it inevitably causes us to think : This new and delete How is the underlying layer of the ? The underlying implementation and malloc also free What is the relationship between ?
So let's start with that new The underlying principle of :
int main()
{
int* pa=new int;
return 0;
}
Go to disassembly in debug mode , Observe the corresponding assembly language :
Here we see , We call new Operator . The compiler calls a function when converting :opreator new A function of , And this function is exactly new The underlying implementation of !
Let's take a look operator new Function source code implementation :
void *__CRTDECL operator new(size_t size) _THROW1(_STD bad_alloc)
{
// try to allocate size bytes
void *p;
while ((p = malloc(size)) == 0)
if (_callnewh(size) == 0)
{
// report no memory
static const std::bad_alloc nomem;
_RAISE(nomem);
}
return (p);
}
From this source code, we can see ,operator new The essence of function is also encapsulated malloc Function of , And when the application for memory space fails, it no longer returns NULL, Instead, throw an exception ! It can be so simple to think ,operator new Functions fail and throw exceptions malloc!
therefore new It works like this :
Bottom call operator new Function to apply for space , After applying for space , Call the constructor of the corresponding class to initialize
Allied ,delete The underlying implementation principle of calls operator delete function , The corresponding is encapsulation free Function of .
Be careful : there operator new Not right new overloaded ! This is often misleading ! This operator new Is a separate function , If you need to call, write it out explicitly opreator new!
// Display call operator new
#include<iostream>
using namespace std;
int main()
{
int* pa = new int;
// Explicit calls must be like this !
void* pa = operator new(sizeof(int));
return 0;
}
operator delete Source code :
void operator delete(void* pUserData)
{
_CrtMemBlockHeader* pHead;
RTCCALLBACK(_RTC_Free_hook, (pUserData, 0));
if (pUserData == NULL)
return;
_mlock(_HEAP_LOCK); /* block other threads */
__TRY
/* get a pointer to memory block header */
pHead = pHdr(pUserData);
/* verify block type */
_ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse));
_free_dbg(pUserData, pHead->nBlockUse);
__FINALLY
_munlock(_HEAP_LOCK); /* release other threads */
__END_TRY_FINALLY
return;
}
C++ The official database corresponds to operator new[] function , Those who are interested can learn by themselves , No more mention here .
What is a template
We know C++ Have the idea of object-oriented programming , One of the most classic is C++ Of Generic Programming , The template is the prerequisite for generic programming . Then let's think about what a template is ?
First , We make experimental reports everyday . The corresponding teachers will ask us to write in a certain format . Usually the teacher will send a sample to us for reference , This example is Templates
Use of templates
In contact, we are learning C When it comes to language ,C Some deficiencies of language .
First C The first deficiency of the language is that it does not support overloading , Let's write a swap function , We need to give different names to different types
and C++ Language provides the mechanism of function overloading , It solves the problem that we don't have to name functions anymore .. But it still needs to write a lot of redundant and repetitive code . To solve such problems .C++ The mechanism of template is introduced , The work of generating corresponding functions is entrusted to the compiler rather than the programmer .
// Syntax of template ---->template keyword
// Use a template to write swap function
template<typename T>
void swap(T& a,T& b)
{
T tmp=a;
a=b;
b=tmp;
}
int main()
{
int a=2,b=1;
swap(a,b);
double c=1.0,d=2.0;
swap(c,d);
return 0;
}
It is not difficult to see , The compiler automatically deduces the corresponding Swap Version of function ! The template used here is function template , The function to be generated can be automatically deduced according to the parameter type
So let's look at such a code
int Add(const int x, const int y)
{
return x + y;
}
template<typename T>
T Add(const T& x, const T& y)
{
return x + y;
}
int main()
{
Add(3, 2);
Add(3.0, 2.0);
return 0;
}
You can see that the first call here calls the existing function Add, Instead of extrapolating .
in other words , If the existing function already has a function that can meet the call requirements , The compiler preferentially calls the matching ! If you can't find it, you will consider the deduction code .
If you want the compiler to deduce , The transformation can be called in this way .
int Add(const int x, const int y)
{
return x + y;
}
template<typename T>
T Add(const T& x, const T& y)
{
return x + y;
}
int main()
{
Add<int>(3, 2);// The compiler will deduce the version
Add(3.0, 2.0);
return 0;
}
This template is called a function template , There is also a template called class template . Class template in our study STL Will be exposed to more ! Let's first look at the syntax definition of the class template
// Use of class templates
#include<iostream>
using std::cout;
using std::endl;
// Angle brackets can also be used class, But never use struct
template<typename T>
class vector
{
public:
vector(size_t capacity=10)
: _a(new T[capacity])
,_size(0)
,_capacity(capacity)
{
}
private:
T* _a;
size_t _size;
size_t _capacity;
};
int main()
{
// The class template must show the type that provides the derivation !
vector<int>v;
return 0;
}
Sometimes you can also separate declarations from definitions , However, the separation of declaration and definition here is limited to declaration and definition in the same file , At this time, let's see how to deal with
// Declaration and definition are separated in the same file
#include<iostream>
using std::cout;
using std::endl;
template<typename T>
class vector
{
public:
vector(size_t capacity=10)
: _a(new T[capacity])
,_size(0)
,_capacity(capacity)
{
}
void push_back(const T& e);
private:
T* _a;
size_t _size;
size_t _capacity;
};
// The separation definition also requires a template declaration ,
// And the class domain to which it belongs becomes vector<T>
template<typename T>
void vector<T>::push_back(const T& e)
{
_a[_size++] = e;
}
int main()
{
vector<int>v;
return 0;
}
Can a template be declared and defined in two files ?
First , Give a clear answer first : Don't put the declaration and definition of the template class in two files !
To verify this practice , We write two documents vector.h ,vector.cpp To verify whether it can be separated :
//vector.h Release statement
#pragma once
#include<iostream>
using std::cout;
using std::endl;
template<typename T>
class vector
{
public:
vector(size_t capacity = 10)
: _a(new T[capacity])
, _size(0)
, _capacity(capacity)
{
}
void push_back(const T& e);
private:
T* _a;
size_t _size;
size_t _capacity;
};
//vector.cpp
#include "vector.h"
template<typename T>
void vector<T>::push_back(const T& e)
{
_a[_size++] = e;
}
template<typename T>
vector<T>::~vector()
{
delete[] _a;
_size = 0;
_capacity = 0;
}
//main.cpp
#include "vector.h"
int main()
{
vector<int>v1;
vector<double>v2;
v1.push_back(1);
v2.push_back(2.0);
return 0;
}
We found that , It happened. link error , Let's see why there are link errors
Let's look at it from the place of invocation , Function calls eventually become call An address , This address is the function address in the symbol table generated by the previous compilation . However , The template is just an empty shell ,** After compiling ,vector.h and vector.cpp The symbol table of is empty !** therefore , Unable to find the address of the function in the corresponding symbol table , So there is a link error !
Solution : stay vector.cpp The file shows instantiation !
// Explicitly instantiate ---> Tell the compiler to deduce like this
template void vector<int>::push_back(const int& e);
// Explicitly instantiate
template void vector<double>::push_back(const double& e);
// Show instantiated classes
template class vector<int>;
template class vector<double>;
Because the cost of separating declaration and definition in two files is very high , So our recommendation is not to separate the declaration and definition of template classes in two files , And used to .h Change to .hpp
summary :
- new and delete The underlying principle is operator new/delete, This is a library function, not right new/delete overloaded , It can be understood as failure throwing exception malloc/free.
- Templates are the foundation of generic programming
- Syntax of template
- Templates do not support the separation of declarations and definitions in two files , The cost is very high !
I hope you can make progress together , If there is any deficiency, please point out .
边栏推荐
- Daily question brushing record (16)
- Sqlite数据库存储目录结构邻接表的实现2-目录树的构建
- Handwriting a simulated reentrantlock
- 商品的设计等整个生命周期,都可以将其纳入到产业互联网的范畴内
- STM32F1與STM32CubeIDE編程實例-旋轉編碼器驅動
- 如何衡量产品是否“刚需、高频、痛点”
- SQL uses the in keyword to query multiple fields
- Automated testing: robot framework is a practical skill that 90% of people want to know
- 用语雀写文章了,功能真心强大!
- Uic564-2 Appendix 4 - flame retardant fire test: flame diffusion
猜你喜欢
Pypharm uses, and the third-party library has errors due to version problems
用语雀写文章了,功能真心强大!
自动化测试:Robot FrameWork框架90%的人都想知道的实用技巧
95. (cesium chapter) cesium dynamic monomer-3d building (building)
[programming problem] [scratch Level 2] December 2019 flying birds
某马旅游网站开发(登录注册退出功能的实现)
Detailed explanation of interview questions: the history of blood and tears in implementing distributed locks with redis
STM32F1与STM32CubeIDE编程实例-旋转编码器驱动
Benchmarking Detection Transfer Learning with Vision Transformers(2021-11)
Basic learning of SQL Server -- creating databases and tables with code
随机推荐
[question de programmation] [scratch niveau 2] oiseaux volants en décembre 2019
Visual Studio Deployment Project - Create shortcut to deployed executable
Introduction to programming hardware
Archery installation test
FFA and ICGA angiography
每日刷题记录 (十六)
2022-07-07:原本数组中都是大于0、小于等于k的数字,是一个单调不减的数组, 其中可能有相等的数字,总体趋势是递增的。 但是其中有些位置的数被替换成了0,我们需要求出所有的把0替换的方案数量:
Reading notes 004: Wang Yangming's quotations
Stm32f1 and stm32cubeide programming example - rotary encoder drive
Trust orbtk development issues 2022
@Detailed introduction of configuration annotation
Robomaster visual tutorial (1) camera
Go learning notes (1) environment installation and hello world
如果在构造函数中抛出异常,最好的做法是防止内存泄漏?
Is it safe for tongdaxin to buy funds?
Basic learning of SQL Server -- creating databases and tables with the mouse
Chisel tutorial - 04 Control flow in chisel
Rectification characteristics of fast recovery diode
用語雀寫文章了,功能真心强大!
CoinDesk评波场去中心化进程:让人们看到互联网的未来