zoukankan      html  css  js  c++  java
  • 第二十三模板 15模板和友元 简单

    //第二十三模板 15模和友元
    //模板类也可以声明为友元,模板类的友元共分三种情况
    //1 非模板友元类或者友元函数
    //2 通用模板类或者友元函数
    //3 特定类型的模板友元类或者友元函数
    
    //1非模板的友元类和友元函数
    //我们可以将任何类或者函数声明为模板类的友元,这样由模板类生成的每个具体类都会正确处理友元类或者友元函数,就好像友元关系已经在具体化的类中声明了一样
    
    
    /*#include <iostream>
    using namespace std;
    const int size=10;
    template<class T>
    class num
    {
    public:
    	num(int Tsize=size);
    	num(const num&r);
    	~num(){delete []pt; }
    	num&operator=(const num&);
    	T&operator[](int offset){ return pt[offset]; }
    	const T&operator[](int offset)const
    	{
    	    return pt[offset];
    	}
    	int GetSize()const{ return numsize; }
    	friend void print(num<T>);//友元
    private:
    	int numsize;
    	T *pt;
    };
    
    
    //定义友元
    template<class T> 
    void print(num<T> sw)
    {
         cout<<"friend函数执行"<<endl;
    	 //for(int i=0; i<sw.numsize; i++){
    	     //cout<<"num["<<i<<"]: \t"<<sw.pt[i]<<endl;
    	 //}
    }
    
    //带一个参数的构造函数
    template<class T>
    num<T>::num(int size):numsize(size)
    {
       cout<<"执行构造函数"<<endl;
       pt = new T[size];
       for(int i=0; i<size; i++){
           pt[i] = 0;
       }
       cout<<"numsize:"<<numsize<<endl;
    }
    
    //定义的复制构造函数
    template<class T>
    num<T>::num(const num&r)
    {
        numsize = r.GetSize();
    	pt = new T[numsize];
    	for(int i=0; i<numsize; i++){
    	    pt[i] = r[i];
    	}
    }
    
    //重载运算符=
    template<class T>
    num<T>&num<T>::operator=(const num&r)
    {
    	if(this == &r){
    	   return *this;
    	   delete []pt;
    	   numsize = r.GetSize();
    	   pt = new T[numsize];
    	   for(int i=0; i<numsize; i++){
    	       pt[i] = r[i];
    	   }
    	}
    	return *this;
    }
    
    int main()
    {
        num<int>one;
        for(int i=0; i<one.GetSize(); i++)
    	{
    	    one[i] = i*2;
    		cout<<one[i]<<endl;
    	}
    	print(one);
    	//for(int i=0; i<one.GetSize(); i++){
    	     //cout<<"num["<<i<<"]: \t"<<one.pt[i]<<endl;
    		 //cout<<one.pt[i]<<endl;
    	//}
    	
    	return 0;
    }*/
    
    
    //正确的方法
    /*
    #include <iostream>
    using namespace std;
    const int size=10;
    template<class T>
    class num
    {
    public:
    	num(int Tsize=size);
    	num(const num&r);
    	~num(){delete []pt; }
    	num&operator=(const num&);
    	T&operator[](int offset){ return pt[offset]; }
    	const T&operator[](int offset)const
    	{
    	    return pt[offset];
    	}
    	int GetSize()const{ return numsize; }
    	friend void print(num<T>);//友元
    private:
    	int numsize;
    	T *pt;
    };
    
    
    void print(num<int>sw)
    {
         cout<<"friend函数执行"<<endl;
    	 for(int i=0; i<sw.numsize; i++){
    	     cout<<"num["<<i<<"]: \t"<<sw.pt[i]<<endl;
    	 }
    }
    
    void print(num<double>sw)
    {
         cout<<"friend函数执行"<<endl;
    	 for(int i=0; i<sw.numsize; i++){
    	     cout<<"num["<<i<<"]: \t"<<sw.pt[i]<<endl;
    	 }
    }
    
    //带一个参数的构造函数
    template<class T>
    num<T>::num(int size):numsize(size)
    {
       cout<<"执行构造函数"<<endl;
       pt = new T[size];
       for(int i=0; i<size; i++){
           pt[i] = 0;
       }
       cout<<"numsize:"<<numsize<<endl;
    }
    
    //定义的复制构造函数
    template<class T>
    num<T>::num(const num&r)
    {
        numsize = r.GetSize();
    	pt = new T[numsize];
    	for(int i=0; i<numsize; i++){
    	    pt[i] = r[i];
    	}
    }
    
    //重载运算符=
    template<class T>
    num<T>&num<T>::operator=(const num&r)
    {
    	if(this == &r){
    	   return *this;
    	   delete []pt;
    	   numsize = r.GetSize();
    	   pt = new T[numsize];
    	   for(int i=0; i<numsize; i++){
    	       pt[i] = r[i];
    	   }
    	}
    	return *this;
    }
    
    int main()
    {
        num<int>one;
    	num<double>two;
        for(int i=0; i<one.GetSize(); i++)
    	{
    	    one[i] = i*2;
    		two[i] = i*5;
    	}
    	print(one);
    	print(two);
    	return 0;
    }*/
    //由于print()函数被声明为一个非模板友元函数,因此它并不是一个模板函数,而只是使用了模板的参数T,这样我们必须在定义函数时具体化模板参数T,该函数才被正确的创建,
    
    
    //2 通用模板友元类的友元函数
    //友元函数被声明为一个模板函数,因此我们不用显示式具体化友元函数的定义部分
    //class num{
    //public:
    //	template<class T1>
    //	friend void print(num<t1>);
    //}
    //template<class T1>将print()友元函数说明为一个模板函数,这样print()函数便可适用于任何类型,注意,通用模板友元函数与模板类的模板参数是不同的,模板类的模板参数是T,而模板友元函数的模板能数是T1
    
    /*
    #include <iostream>
    using namespace std;
    const int size=10;
    template<class T>
    class num
    {
    public:
    	num(int Tsize=size);
    	num(const num&r);
    	~num(){delete []pt; }
    	num&operator=(const num&);
    	T&operator[](int offset){ return pt[offset]; }
    	const T&operator[](int offset)const
    	{
    	    return pt[offset];
    	}
    	int GetSize()const{ return numsize; }
    	//friend void print(num<T>);//友元
    	//定义模板友元函数
    	template<class T1>
    	friend void print(num<T1>);
    	//函数就变成了一个通用的模板友元函数,又叫非约束模板友元函数
    
    private:
    	int numsize;
    	T *pt;
    };
    
    
    //这里的template<class T1>是函数所表示的模板
    template<class T1> void print(num<T1>sw)
    {
    	cout<<"friend函数执行!";
    	for(int i=0; i<sw.GetSize(); i++){
    	   cout<<"num["<<i<<"]:\t"<<sw.pt[i]<<endl;
    	}	
    }
    
    
    //带一个参数的构造函数
    template<class T>
    num<T>::num(int size):numsize(size)
    {
       cout<<"执行构造函数"<<endl;
       pt = new T[size];
       for(int i=0; i<size; i++){
           pt[i] = 0;
       }
       cout<<"numsize:"<<numsize<<endl;
    }
    
    //定义的复制构造函数
    template<class T>
    num<T>::num(const num&r)
    {
        numsize = r.GetSize();
    	pt = new T[numsize];
    	for(int i=0; i<numsize; i++){
    	    pt[i] = r[i];
    	}
    }
    
    //重载运算符=
    template<class T>
    num<T>&num<T>::operator=(const num&r)
    {
    	if(this == &r){
    	   return *this;
    	   delete []pt;
    	   numsize = r.GetSize();
    	   pt = new T[numsize];
    	   for(int i=0; i<numsize; i++){
    	       pt[i] = r[i];
    	   }
    	}
    	return *this;
    }
    
    int main()
    {
        num<int>one;
    	num<double>two;
        for(int i=0; i<one.GetSize(); i++)
    	{
    	    one[i] = i*2;
    		two[i] = i*5;
    	}
    	print(one);
    	print(two);
    	return 0;
    }*/
    
    /*
    // 3 特定类型模板友元函数
    #include <iostream>
    using namespace std;
    const int size=10;
    template <template <class T> class TT, class T>
    ostream & operator<< (ostream &out, const TT<T> &tt);
    template<class T>
    class num
    {
    public:
    	num(int Tsize=size);
    	num(const num&r);
    	~num(){delete []pt; }
    	num&operator=(const num&);
    	T&operator[](int offset){ return pt[offset]; }
    	const T&operator[](int offset)const
    	{
    	    return pt[offset];
    	}
    	int GetSize()const{ return numsize; }
    	
    	friend ostream &operator<< <>(ostream &out, const num<T> &tt);
    private:
    	int numsize;
    	T *pt;
    };
    
    
    template<template <class T> class TT, class T>
    ostream &operator <<(ostream &out, const TT<T> &tt)
    {
        out<<"调用operator<<函数"<<endl;
    	for(int i=0; i<tt.GetSize(); i++){
    	   out<<"["<<tt[i]<<"]"<<endl;
    	}
    	return out;
    }
    
    
    //带一个参数的构造函数
    template<class T>
    num<T>::num(int size):numsize(size)
    {
       cout<<"执行构造函数"<<endl;
       pt = new T[size];
       for(int i=0; i<size; i++){
           pt[i] = 0;
       }
       cout<<"numsize:"<<numsize<<endl;
    }
    
    //定义的复制构造函数
    template<class T>
    num<T>::num(const num&r)
    {
        numsize = r.GetSize();
    	pt = new T[numsize];
    	for(int i=0; i<numsize; i++){
    	    pt[i] = r[i];
    	}
    }
    
    //重载运算符=
    template<class T>
    num<T>&num<T>::operator=(const num&r)
    {
    	if(this == &r){
    	   return *this;
    	   delete []pt;
    	   numsize = r.GetSize();
    	   pt = new T[numsize];
    	   for(int i=0; i<numsize; i++){
    	       pt[i] = r[i];
    	   }
    	}
    	return *this;
    }
    
    int main()
    {
        num<int>one;
    	num<double>two;
        for(int i=0; i<one.GetSize(); i++)
    	{
    	    one[i] = i*2;
    		two[i] = i*5;
    	}
    	cout<<one;
    	cout<<two;
    	return 0;
    }*/
    //该程序与前一个程序同样的结果,不过该程序,也就是在模板类外部声明特定模板友元函数比前一个程序复杂
    //1 我们必须在模板类前面声明模板友元函数,
    //2 在模板类中具体化模板友元函数
    //3 为这个特定的模板友元函数提供模板定义
    

      

  • 相关阅读:
    CNN5 调用 C实现pool2d im2col col2im
    CUDA学习3 Max pooling (python c++ cuda)
    CUDA学习2 基础知识和Julia示例
    CUDA学习1 在Visual Studio和CodeBlocks上配置
    线性搜索
    CNN4 参数优化
    CNN3 im2col
    CNN2 多层卷积
    爬虫:Scrapy8
    爬虫:Scrapy7
  • 原文地址:https://www.cnblogs.com/xiangxiaodong/p/2711692.html
Copyright © 2011-2022 走看看