登录  | 立即注册

游客您好!登录后享受更多精彩

查看: 59|回复: 0

C++进阶知识02.动态内存分配、模板

[复制链接]

82

主题

2

回帖

107

积分

网站编辑

积分
107
发表于 2025-1-24 02:00:22 | 显示全部楼层 |阅读模式

动态内存分配

普通变量的动态内存分配

C++ 程序的内存分为两部分

  • <b>栈:</b>在函数内部声明的所有变量都将占用栈内存。
  • <b>堆:</b>这是程序中未使用的内存,在程序运行时可用于动态分配内存。

而 new 关键字就是 C++ 用于动态内存分配的。

#include<iostream>
using namespace std;

int main(){
    double *d = nullptr;
    d = new double;
    *d = 123;
    cout<<*d<<endl; // 123
}

数组的动态内存分配

使用 new 关键字为一维数组分配内存

#include<iostream>
using namespace std;

int main(){
    int *arr = nullptr;
    arr = new int[10];
    *(arr) = 1;
    *(arr+1) = 2;
    // 直接用数组形式的下标范围
    cout<<arr[0]<<endl;
    // 计算指针偏移量也可以
    cout<<*(arr)<<endl;
    cout<<*(arr+1)<<endl;
}

使用 new 关键字为二维数组分配内存

#include<iostream>
using namespace std;

int main(){
    int **array;
    array = new int*[10];
    for(int i=0; i<10; i++){
        array[i] = new int[10];
    }  
    // 二维数组范围。先拿到一维数组的地址,再加上偏移量。
    // 最后从地址中拿数据
    cout<<*(array[0]+0)<<endl;
    cout<<*(array[0]+1)<<endl;
}

内存释放

普通变量直接 delete 变量名。数组稍微特殊点。

int main(){
    int **array;
    array = new int*[10];
    for(int i=0; i<10; i++){
        array[i] = new int[10];
    }  

    // 二维数组先释放一维数组,再释放二维数组。
    for (int i = 0; i < 10; i++){
        delete []array[i];
    }
    delete []array;

    // cout<<*(array[0]+0)<<endl;
    // cout<<*(array[0]+1)<<endl;
}

函数模板

函数模板是函数的抽象,它与普通函数相似,唯一的区别就是函数参数的类型是不确定的,函数参数的类型只有在调用过程中才被确定。

template<typename 占位符, typename 占位符> 返回值类型 函数名(参数列表){
    // 函数体
}

定义一个适用于 int、double、float 的 add 运算函数。

#include<iostream>
using namespace std;

template<typename T> T add(T one, T two){
    return one+two;
}

int main(){
    cout<<add(1,1)<<endl;
    cout<<add(1.1,1.2)<<endl;
}

函数模板并不是一个函数,它相当于一个模子,定义一次即可使用不同类型的参数来调用该函数模板,这样做可以减少代码的书写,提高代码的复用性和效率。需要注意的是,函数模板不会减少可执行程序的大小,因为编译器会根据调用时的参数类型进行相应的实例化。所谓实例化,就是用类型参数替换模板中的模板参数,生成具体类型的函数。<b>实例化可分为隐式实例化与显式实例化。</b>

隐式实例化

隐式实例化是根据函数调用时传入的参数的数据类型确定模板参数 T 的类型,模板参数的类型是隐式确定的。比如调用 add(1,1) 会根据模板实例化出一个 int 类型的函数:

int add(int t1,int t2) { 
    return t1 + t2; 
} 

每一次调用时都会根据不同的类型实例化出不同类型的函数,最终的可执行程序的大小并不会减少,只是提高了代码的复用性。

显示实例化

显示实例化就是显示的创建一个模板的实例。

#include<iostream>
using namespace std;

template<typename T> T add(T one, T two){
    return one+two;
}

// 可以省略。
template int add(int t1, int t2);

int main(){
    // 调用显示实例化的模板实例
    cout<<add<int>(1,1)<<endl;
    cout<<add(1.1,1.2)<<endl;
}

类模板

template <typename type> ret-type func-name(parameter list){}
template <typename type, typename tyep> ret-type func-name(parameter list){}

定义一个基于模板的含有两个元素的元组。

#include<iostream>
using namespace std;

template<class T1,class T2> class Tuple{
    public:
        T1 element1;
        T2 element2;
        Tuple(T1 t1,T2 t2);
        T1 sum(T1 t1, T2 t2);
};
// 构造方法
template<class T1, class T2> Tuple<T1, T2>::Tuple(T1 t1, T2 t2){
    this->element1 = t1;
    this->element2 = t2;
}

// 元组元素求和
template<class T1,class T2> T1 Tuple<T1,T2>::sum(T1 t1, T2 t2){
    return t1+t2;
}

int main(){
    Tuple<int,double> *t = new Tuple<int,double>(10,11.2);  
    cout<<t->sum(1,2)<<endl; // 3
    cout<<t->element1<<endl; // 10
    cout<<t->element2<<endl; // 11.2
}
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|断点社区 |网站地图

GMT+8, 2025-2-5 17:44 , Processed in 0.052978 second(s), 27 queries .

Powered by XiunoBBS

Copyright © 2001-2025, 断点社区.

快速回复 返回顶部 返回列表