前言:许久没有做C++相关项目了,想通过小项目从头review一遍c++的核心知识点。希望通过这个系列博客记录自己遗忘或新发现的知识点。如果也能对你有所帮助,我深表荣幸!共勉!
vector作为C++ STL库中常见的模板类。
-
动态数组&扩容原理:对比与c中数组,最容易想到的特性它是一个动态数组;vector的扩容原理及优化方式是值得学习和思考的地方。
-
尾部增删常数时间:由于vector内部有尾部迭代器,对于尾部数据的增删,在O(1)时间完成。
-
非尾部增删O(n)时间:增删首部或中间数据,需要移动后续数据,故在O(n)时间内完成。
1.构造函数 MyVector() noexcept{}: 从构造函数入手来构建自己的vector类。如下图所示,我们可以通过定义vector<T> 类型的对象或通过new的方式来构造一个 vector<T> 对象/ vector<T>* 对象指针。
#include<iostream>
#include<vector>
using namespace std;
class A{
public:
A(){cout<<"A构造开始"<<endl;};
~A(){cout<<"A析构开始"<<endl;};
};
int main(){
vector<A> test;
vector<A>* ptr = new vector<A>();
cout<<"对象test初始容量:"<<test.capacity()<<endl; //对象test初始容量:0
cout<<"对象test初始数据量:"<<test.size()<<endl; //对象test初始数据量:0
cout<<"对象指针ptr初始容量:"<<ptr->capacity()<<endl; //对象指针ptr初始容量:0
cout<<"对象指针ptr初始数据量:"<<ptr->size()<<endl; //对象指针ptr初始数据量:0
delete ptr;
return 0;
}
若不设定参数,则调用默认无参构造函数 vector( const Allocator& = Allocator() ); 即通过堆空间配置器来申请空间;通过输出的capacity()可以看到STL中vector初始申请的空间大小为0.
这里有几个值得注意的点:
- 指针和对象调用成员函数的形式不一样。
- new 关键字的底层逻辑。在我之前的学习中其实并没有注意这一点,只知道new和delete一般一起使用,防止出现内存泄漏。
1.new运算符的底层逻辑&与malloc区别:
- 对于new其包含以下几个步骤(申请空间&调用构造函数):
- operator new:申请空间 void* operator new(size_t size_type);返回指向一个原始的内存地址的指针。通常需要用static_cast<T*>() 转化到默认/用户类型的指针。当然这个函数可以重载,如果重载则调用类重载的operator new。
- 调用类型T的构造函数:前面已经通过operator new 申请内存。接着调用T的构造函数完成类型初始化。
- 返回类型地址指针。
- 对于malloc(库函数)(仅申请空间):
- 空间申请:void* malloc(size_t size_type);返回一个指向原始内存地址的指针。并且你需要指定申请内存的大小。
- 完事。删除内存调用 free。
- 注意:malloc只适用于基础类,不可用于自定义类。