一、构造函数
1.匿名对象与构造函数
在C++中,匿名对象是一个临时对象,它没有名称,通常在对象创建后,只使用一次后就被销毁。创建匿名对象的方式是在创建对象时不使用变量名。
下面是创建匿名对象的几种方式:
-
直接使用构造函数创建匿名对象
-
使用new关键字创建匿名对象
-
使用函数返回对象
-
使用初始化列表
注意,匿名对象通常在对象被创建后,只使用一次后就被销毁。如果你想要持有这个匿名对象的引用或指针,那么你需要将其转换为有名字的对象。
2.迭代器区域构建构造函数
模板形式便于不同类型迭代器使用,头尾两个迭代器规定数组范围,利用迭代器向这个范围的数据尾插数据。
二、拷贝构造(swap写法)
1.值传递、引用传递、临时变量
-
值传递:方法调用时,实际参数把它的值传递给对应的形式参数,方法执行中形式参数值的改变不影响实际参数的值。
-
引用传递:也称为传地址。
-
方法调用时,实际参数的引用(地址,而不是参数的值)被传递给方法中相对应的形式参数,在方法执行中,对形式参数的操作实际上就是对实际参数的操作,方法执行中形式参数值的改变将会影响实际参数的值。
-
临时变量通常在几种情况下产生
-
1. **值传递**:当函数以值传递方式返回对象时,编译器通常会生成一个临时变量来存储返回的对象。
2. **类型转换**:当发生类型转换时,特别是涉及到用户自定义类型的转换,也会产生临时变量。这包括隐式和显式(强转)类型转换。
3. **常量引用类型**:如果函数参数是常量引用类型,而传入的实参不匹配但可转换,或者实参是一个右值(非左值),那么编译器会产生一个临时变量。
4. **函数参数传递**:当函数参数需要通过值传递,但实参与形参类型不匹配时,编译器可能会生成临时变量以适配类型。
5. **特定语言构造**:在某些编程语言中,特定的语言构造会在背后产生临时变量。例如,在C++中,某些情况下返回类对象时,即使没有显式的临时变量声明,也可能由于编译器优化而实际产生了临时变量。
6. **表达式计算**:在计算涉及多个步骤的复杂表达式时,编译器可能会生成临时变量来保存中间结果。
7. **异常处理**:在异常处理中,当抛出一个异常对象而尚未被捕获时,该异常对象就是一个临时变量,它在内存中的生命周期将持续到被捕获为止。
8. **模板实例化**:在使用模板时,不同类型的实例化可能会导致创建临时变量以适应不同的类型参数。
临时变量的产生通常是由编译器自动管理的,旨在支持程序的运行和提高代码的效率。 开发者可以通过避免不必要的临时变量生成来优化程序性能,例如通过使用引用传递而非值传递,或者通过避免不必要的类型转换。
三、析构函数
如果指针指向空间不为空就delete[ ]空间(空间由new[ ]在堆上开辟)的资源,同时重置vector成员数据
四、读写与只读迭代器
1.const
**const关键字的主要作用是定义不允许被改变的对象**。在C++中,它用于指定变量、函数参数、成员函数以及类的属性等不应被修改,从而提供程序的健壮性和可维护性。
1. **定义常量**:使用const可以定义常量,这些常量的值一旦被设定后就不能改变。这有助于防止在程序运行过程中意外修改这些值,同时也向其他开发者明确表明这些值是只读的。
2. **类型检查**:当const用于函数参数时,它允许编译器进行更严格的类型检查,确保传入的参数不被意外修改,提高了代码的安全性和可靠性。
3. **保护数据**:const通过确保某些数据保持恒定不变,帮助保护了程序中的关键数据不被修改,这对于数据安全和程序稳定性至关重要。
4. **替代宏**:与预处理器的#define相比,使用const定义常量更加安全且符合C++语言的作用域规则,避免了宏定义带来的潜在问题。
5. **指针和引用**:const可用于修饰指针和引用,指向常量的指针(pointer to const)或对常量的引用(reference to const)保证了它们所指向或引用的对象在程序中的不变性。
6. **接口设计**:在类的设计中,将getter方法中的成员变量声明为const,可以保证该方法不会修改任何成员变量的状态,这对于线程安全和类的设计是非常重要的。
7. **编译优化**:const对象为编译器提供了额外的优化机会,因为const对象表达出了不变的语义,编译器可以据此生成更优化的代码。
在使用const时,需要注意以下几点以确保正确性和程序的高效运行:
1. **初始化要求**:由于const对象一经定义便不可更改,因此必须在定义时对其进行初始化。
2. **文件内有效性**:默认情况下,const对象仅在其定义的文件内有效,若需要在多个文件间共享const对象,需使用extern关键字。
3. **顶层底层const**:理解顶层const和底层const的概念对于正确地处理指针和引用至关重要。顶层const指的是指针本身是const,而底层const指的是指针所指向的对象是const。
4. **constexpr与const**:虽然两者都用于声明常量,但constexpr表示的常量必须在编译时就能计算出来,而const则没有这个限制。
五、数据量与数组容量
通过vector的三个指针即可算出数组中的数据量与容量
六、reserve()与resize()
(1)拷贝构造
拷贝构造函数,也称为复制构造函数,是一种特殊的构造函数,它由编译器调用来完成同一类的其他对象的构建及初始化。拷贝构造函数的形参必须是引用,但并不限制为const
,一般普遍的会加上const
限制。拷贝构造函数经常用在函数调用时用户定义类型的值传递及返回。它要调用基类的拷贝构造函数和成员函数。拷贝构造函数的主要目的是用其他对象的数据来初始化当前对象,并没有期望更改其他对象的数据。12
在C++中,以下三种情况需要调用拷贝构造函数:
- 一个对象作为函数参数,以值传递的方式传入函数体;
- 一个对象作为函数返回值,以值传递的方式从函数返回;
- 一个对象用于给另外一个对象进行初始化(常称为赋值初始化)。
如果类中包含动态分配成员或包含指针成员,应该提供拷贝构造函数。在提供拷贝构造函数的同时,也应该考虑重载"="赋值操作符。拷贝构造函数的参数必须是一个引用,这是因为如果参数不是引用,就会调用该类的拷贝构造函数,从而造成无穷递归的调用。
如果没有显式地定义拷贝构造函数,那么编译器会自动生成一个默认的拷贝构造函数。这个默认的拷贝构造函数简单地使用“老对象”的成员变量对“新对象”的成员变量进行一一赋值。对于简单的类,这个默认的拷贝构造函数一般是够用的。然而,对于包含指针成员的类,这个默认的拷贝构造函数(浅拷贝)可能会导致新对象中的指针指向和初始化对象指针指向一致,当用来初始化的对象在释放内存时会释放掉指针指向的内存,而新创建的对象在释放时会出现程序错误。
resize()考虑是否扩容,还要考虑数据量是缩是扩,仍然是通过vector的三个成员参数实现
七、尾插尾删
八、erase( )和insert( )
1.迭代器失效
注意原迭代器经扩容等操作后可能失效,要返回更新过的迭代器
九、重载[ ]下标访问
分只读与读写、以数组下标访问的方式取得数据
十、成员变量
十一、测试案例
1.三种循环访问方式
2.插入函数的运用
3.插入函数的返回值
迭代器失效