(笔记C++)第二十五节课:类模板与内存管理

16 篇文章 0 订阅

一 类模板

(1)概念

类模板中定义的函数参数类型或者属性等数据类型可以参数化。

template

class 类型

{

//...

}

(2)模板类的继承

(3) 模板类的声明

(4) 模板类中的static

二 成员模板

2.1 为什么要使用成员模板

2.2 成员模板的实现

三 关键词-typename

3.1 内嵌依赖类型名

内嵌:是指在类的内部定义的

依赖:依赖于摸一个模板参数

类型名:最终要指出的这个类型名

3.2 实例

四 using 给模板起别名

五 实例化

5.1 #pragma once

1、ifndef方法是c/c++的标准支持,比较常用的方式

#pragma once一般由编译器提供保证,功能是保证同一个文件不会被包含多次

visual studio 2017之后的版本新建头文件都会自带#pragma once    

2、兼容性:#pragma once产生于ifndef之后,ifndef不受任何编译器的限制,而#pragma once方法有 些编译器不支持(较老的编译器(gcc3.4之前的不支持)),兼容性不够好,

3、ifndef可以针对文件中的一部分代码,而#pragma once只针对整个文件

4、ifndef 更加灵活,兼容性好,#pragma once操作简单,效率更高。

5.2 隐式实例化

隐式实例化是指在函数调用的时候,如果没有发现与之相匹配的函数存在,编译器会寻找同名的函数模板,如 果可以成功进行参数的推演,就对函数模板实例化。

类模板同上

5.3 显示实例化

显示实例化:外部实例化,在不发生函数调用的时候将函数模板实例化

类模板同上

5.3.1 函数模板的显示实例化

template [返回值类型] [函数名](函数参数列表)

template void func(const int&);

5.3.2 类模板的显示实例化

template class Test;

作用:减少隐式实例化实例多个函数和类的开销,只实例化一次(不同编译器处理机制可能不同)

5.4 模板全特化和偏特化

5.4.1 为什么要模板特化?

因为编译器认为,对于特定的类型,如果你能对某一个功能更好的实现,那么就该听你的

模板实例化时会优先匹配“模板参数”最符合那个特化的版本

模板特化的前提已要求模板的泛化。

(1) 类模板的全特化

(2) 类模板的偏特化

模板参数数量偏特化

(3)类模板参数范围偏特化

int --->const int   T -->T*   T--->T&

# 六 内存管理

## 6.1 c++内存管理

```c++
大多数问题都是由于内存泄漏导致的。
```

## 6.2 内存分析诊断工具 valgrind

```c++
sudo apt-get update
sudo apt-get install -f
sudo apt-get intall valgrind
```

使用 valgrind:

<img src="C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220713170445935.png" alt="image-20220713170445935" style="zoom:50%;" />

## 6.3 如何避免内存泄漏

```c++
new/delete的成对使用
new[]/delete[]成对出现
人为的控制new/delete的问题,无法杜绝内存泄漏
```

## 6.4  c++为什么没有提供GC机制(垃圾回收机制)

```c++
没有共同基类:c++是从c语言发展而来,允许直接操作指针,允许将一个类型转换位另一个类型
对于一个指针无法知道它真正指向的类型,而java和c#都有一个共同的基类。
系统开销:GC机制所带来的系统开销,违反了c++的设计哲学--》不为不必要的功能支持代价,不符合c++高效的特性,不符合底层工作的要求。
消耗内存:c++产生的年代内存比较小
替代方法:c++有析构函数,智能指针,引用计数器等去管理资源的释放。
```

## 6.5 智能指针

### 6.5.1 作用

```c++
帮助开发者动态的开辟和释放申请的空间,能有效的防止内存泄漏。
```

### 6.5.2 分类

```c++
分类:
    auto_ptr(c++98): 被c++11智能指针替代,不再使用
    unique_ptr(c++) 独占指针
    share_ptr(c++):共享指针
    weak_ptr(c++):弱指针 
    int *p:裸指针
```

### 6.5.3 share_ptr

共享式指针:

```c++
多个指针可以同时指向一个对象(共享所有权,协同工作)
当最后一个指针被销毁或者指向其它对象时,这个对象会被释放
```

工作原理:引用计数增加/减少(原子操作)

```c++
引用计数增加:
    用一个智能指针初始化另一个智能指针
    函数传参:传递一个智能指针
    函数返回值:返回一个智能指针
引用计数减少:
    给智能指针赋予新值,指向一个新对象
    局部的智能指针离开其作用域。
```

定义:

```c++
share_ptr<指向的类型> 智能指针变量名
```

```c++
#include <iostream>
#include <memory>
#include <string>
using namespace std;
class A
{
public:
    A()
    {
        cout << "A的无参构造" << endl;
    }
    A(int n)
    {
        m_a = n;
        cout << "A的有参构造" << endl;
    }
    int m_a;
    ~A()
    {
        cout << "A的析构函数" << endl;
    }
};
shared_ptr<A> test()
{
    shared_ptr<A> temp(new A);
    return temp;
}
void Func(shared_ptr<A> temp)
{
    cout << temp->m_a << endl;
}
int main(void)
{
    //int *p = new int(5);  //p是裸指针
    //shared_ptr<int> p = new int(5); //初始化:调用类型转换构造函数 explicit
    shared_ptr<int> p(new int(5));
    cout << *p << endl;

    shared_ptr<string> s(new string("helloworld"));
    cout << *s << endl;
    int num = 100;
    //shared_ptr<int> p2(&num);   //智能指针常用于堆空间,指向栈空间的时候,会导致内存释放两次

     //A *pa = new A(100);
    //delete pa;
    shared_ptr<A> pa(new A);
    shared_ptr<A> res = test();
    Func(pa);
    shared_ptr<A> pa2(pa);
    return 0;
}
```

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值