new和delete重载,模板

new和delete

Tmp* p=new Tmp();------new operator(不可重载)
申请内存(调用operator new)可以重载
调用构造


delete p ;-----delete operator(不可重载)
调用析构
内存释放(operator delete)可以重载



void* operator new(size_t size)重载函数
{
    cout<<"void* operator new(size_t size)"<<endl;
    void* p=malloc(size);
    return p;
}


void operator delete(void* p)
{
    cout<<"void operator delete(void* p)"<<endl;
    free(p);
}

堆上的资源属于是外部资源

申请/释放外部资源————用户态没有权限,内核态有权限

堆上的内存申请和释放的过程需要内核态完成————从用户态切换到内核态

系统调用:cout,printf,cin,scanf(调用外部资源的都得进行系统调用)

内存池:用户态自己维护的一大段内存

重载new和delete相当于留下了一个可修改的端口,可以指定内存的申请和释放的内存池

c++自带的内存池:_Alloc

MFC编译器:new和delete进行全局重载时检测内存泄露的工具
有一个全局链表,当new时,将地址加入到链表,delete时将地址从链表中删除,,程序执行完了后,打印链表中的数据,如果有则内存泄漏

模板

重载:函数名相同,参数列表不同(静多态,编译时期的多态,早绑定)

模板不可以直接运行,模板会在编译时期根据使用情况生成对应的函数指令

模板不编译,模板生成的函数指令会编译,模板中的语法错误会在生成对应的指令时候被编译错误
函数模板有类型自推的能力,使用函数模板可以不用传模板类型的参数eg:compare(10,20),int 可不用写

template<typename T>
bool compare(T a,T b)
{
    return a>b;
}

int main()
{
   compare(10,20);
   if(compare("aaa","bbb"))传入const char*会直接比较地址
   {
      cout<<"aaa">"bbb"<<endl;
   } 
}


template<typename T>
void sort(T* arr,int len)
{
if(srr==NULL)return;
 for(int i=0;i<len-1;++i)
 {
   for(int j=i+1;j<len-i-1;++j)
   {
      T temp=arr[i];
      if(arr[j]<arr[i])
      {
        arr[i]=arr[j];
        arr[j]=tmp;
      }
 }
 
}


模板的完全泛化,部分特例化,完全特化


template<class T>完全泛化,只要是类型就可以根据该模板写出对应的函数
void fun(T a)
{
   T x,y;
   cout<<"T type"<<typeid(T).name()<<endl;
   cout<<"a type"<<typeid(a).name()<<endl;
}



template<class T>
void fun(T* a)部分特例化,只要是指针就可以
{
   T x,y;
   cout<<"T type:"<<typeid(T).name()<<endl查看T的类型
   cout<<"a type:"<<typeid(a).name()<<endl查看T的类型
}
template<>完全特化,必须为char*
void fun<char*>(char* a)
{
   
} 

类模板

不编译,会在编译时期根据使用方式,生成对应的类代码(指令)
类模板中在main函数中没有使用到的成员方法不实现是不会报错的,只有在main中调用才会报错
类模板使用的时候必须加上模板类型的参数,无法自己推导类型函数
类模板的成员方法只能在头文件中实现或者在使用到的cpp文件中实现,不能分开实现在.h和另一个.cpp(除了写main函数的.cpp文件)
因为类模板在编译时期将使用到的成员方法生成对应的指令,编译器只针对单文件,如果将类模板的成员方法实现在了其他文件,编译时期使用到的该方法的文件不可见,就无法生成对应的指令,————无法解析的外部符号
在另一个文件中,因为没有使用到它的地方所以不编译,因此链接时也无法找到

template<class T,int N>
class Stack
{
   T data[N];
   public:
   void push(const T&x);
}

int main()
{
    Stack<int,100> is;
    Stack<int,10> ist;
}
template<typename T>

class Arr
{
 private:
      T* arr;
      int _len;
      int _val_len;
public:
    Arr()
    {
       cout<<"Arr()"<<endl;
    }   
    void push_back(const T&val);
};
int main()
{
   Arr<int> arr;必须加类型,不会自己推导
}


类模板的特例化
template<>
class Arr<const char*>
{
private:
    const char** arr;
      int _len;
      int _val_len;
const char** arr;
  public:
   Arr()
    {
       cout<<"Arr<const char*>"<<endl;
    }   
    void push_back(const char*val);
友元函数模板
template<typename TT>
friend ostream& operator<<(ostream& out,Arr<TT>& src);
};

模板里的成员方法在类外实现时,多了个T,因为Arr是模板,加上T才是类名
template<typedef T>
void Arr<T>::push_back(const T&val);

template<typedef T>
ostream& operator<<(ostream& out,Arr<T>& src)
{
   for(int i=0;i<src.size();++i)
   {   
        out<<src[i]<<" ";
   }
   cout<<endl;
}




int main()
{
   Arr<const char*> arr;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1. 基类说明 1.1 基类结构图 1.2 基类说明 1.2.1 BaseEditClass BaseEditClass是所有单表编辑功能的基类。BaseEditClass从NSGForm继承,以处理统一的界面和字体风格。 BaseEditClass抽象出了编辑类功能通用的方法并定义为基类方法,以便子类继承,并增加自己的代码。  自定义属性 名称 说明 DataTable 功能所编辑的数据表 DataState 功能所处的状态:浏览(dsBrowse)、新增(dsInsert)、编辑(dsEdit) BatchSave 是否批量提交数据表,默认为False DeleteWarn 在删除记录时是否提示,默认为True  自定义方法 名称 说明 FormInit 在FormLoad时被调用,具体功能中可重载该方法添加自定义的初始化代码 PostData 具体功能中需要重载该方法,并调用具体的TableAdapter.Update(row),以保存数据至数据库。 RefreshData 统一的刷新数据表过程,具体功能中需要重载该方法,并调用具体的TableAdapter.Fill(DataTable),以查询数据 DataValid 统一的数据验证方法,在保存数据前被调用。具体功能中可重载该方法添加自定义的数据校验代码 NewRecord 在新增数据时被调用,在具体过程中可重载该方法添加自定义的新增记录默认值 SaveData 保存数据的方法,具体功能中调用该过程保存数据 DeleteData 删除数据的方法,具体功能中调用该过程删除数据 CancelData 取消数据修改的方法,具体功能中调用该过程取消数据修改 1.2.2 BaseGridEdit BaseGridEdit是所有直接使用DataGridView进行编辑的功能的基类。BaseGridEdit从BaseEditClass继承。 自定义属性 名称 说明 Grid 编辑所用的DataGridView 自定义方法 名称 说明 RecordValid 统一的数据验证方法,在单条保存数据前被调用。具体功能中可重载该方法添加自定义的数据校验代码 1.2.3 BaseGridEditForm BaseGridEditForm是所有直接使用DataGridView进行编辑的功能的模板。所有直接使用DataGridView进行编辑的功能都需要从该模板拷贝后进行修改。 2. 模板使用方法 2.1 BaseGridEditForm 使用BaseGridEditForm需要按以下四步操作就可以得到需要的功能。 一、 先从BaseGridEditForm拷贝文件到工程后修改类名、命名空间 二、 在项目的数据集中增加TableAdapter,以查询需要维护的指定的数据表 三、 将DataGridView绑定到新增的数据表 四、 修改以下基类方法 名称 说明 构造方法 增加”DataTable属性=新增数据表”的代码 FormInit 增加需要的Form初始化代码,如RefreshData以获得数据 PostData 增加一行代码:新增的TableAdapter.Update(row) RefreshData 增加使用新增TableAdapter.Fill(DataTable)的代码,以获得查询数据。注意:代码需要写在IsRefreshData = true;和 IsRefreshData = false;语句的中间 RecordValid 增加自定义的数据校验语句。 NewRecord 增加自定义的新增数据默认值代码。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值