c++友元和模板

 友元

 

1.友元的概念
             C++提供了一种机制(语法规则):让其它的函数或者其它的类可以使用本类中定义的私有成员

   2.友元函数
            定义:在普通函数的前面加上firend关键字,该函数就变成了友元函数
            语法规则:   friend  函数的返回值  函数名称(形参);  //声明友元函数
           
   3.友元类
            语法规则:friend  class 类名;   //声明友元类
 

注意:友元函数的定义可以写在类的里面或者类的外面

#include <iostream>

using namespace std;

//定义银行账户类
class Bankcount
{
public:
	Bankcount(string _name,double _money)
	{
		name=_name;
		money=_money;
	}
	//声明show函数是Bankcount类的友元函数
	friend void show(Bankcount &other)
	{
		cout<<"户主是: "<<other.name<<endl;
		cout<<"余额是: "<<other.money<<endl;
	}
private:
	double money;  //余额
	string name;   //账户名字
};




int main()
{
	Bankcount b("马云",1000000000000000.0);
	show(b);
}

#include <iostream>

using namespace std;

//定义银行账户类
class Bankcount
{
public:
	Bankcount(string _name,double _money)
	{
		name=_name;
		money=_money;
	}
	//声明show函数是Bankcount类的友元函数
	friend void show(Bankcount &other);
	
private:
	double money;  //余额
	string name;   //账户名字
};

//友元函数的定义写在类的外面
void show(Bankcount &other)
{
	cout<<"户主是: "<<other.name<<endl;
	cout<<"余额是: "<<other.money<<endl;
}


int main()
{
	Bankcount b("马云",1000000000000000.0);
	show(b);
}

 友元类,以及互为友元类

#include <iostream>

using namespace std;

class Person;  //前向引用声明(告诉编译器,我有定义Person类,只是说在后面定义,我先跟编译器打声招呼)

//定义银行账户类
class Bankcount
{
public:
	Bankcount(string _name,double _money)
	{
		name=_name;
		money=_money;
	}
	//声明Person类是我的友元类
	friend class Person;
	
private:
	double money;  //余额
	string name;   //账户名字
};


//定义Person类--》跟银行账户类没有关系
class Person
{
public:
	Person(string _name)
	{
		name=_name;
	}
	
	//我想查看某个人的银行账户信息
	void show(Bankcount &other)
	{
		cout<<"账户是: "<<other.name<<endl;
		cout<<"余额是: "<<other.money<<endl;
	}
private:
	string name;
};



int main()
{
	Bankcount b("马云",1000000000000000.0);
	Person p("老师");
	p.show(b);
	
}
#include <iostream>

using namespace std;
class A; //前向引用:只是告诉编译器后面有定义A这个类,但是这个类中具体有什么成员还是不知道

class B
{
public:
    void show(A _new);
    
	//声明了A是B的友元类
    friend class A;
private:
    int c;
    double d;
};

class A
{
public:
	void show(B _new)
    {
        cout << "c: " << _new.c << endl;
        cout << "d: " << _new.d << endl;
    }
	//声明了B是A的友元类
    friend class B;
private:
    int a;
    double b;
};

void B::show(A _new)
{
    cout << "a: " << _new.a << endl;
    cout << "b: " << _new.b << endl;
}



int main()
{
    A aa;
    B bb;

    aa.show(bb);
    bb.show(aa);
}

模板(参数和返回值抽象为模板)--》泛型编程

模板是C++中引入的一种泛型编程技术
   泛型:通用类型
   1.引入模板
             函数重载非常的啰嗦,需要动手写N个版本的add
                 int add(int a,int b)
                 double add(double a,double b)
            C++的设计者想了一个优化的办法,上面两个版本的add仅仅只是参数类型不同而已,我为何不可以把参数类型抽象出来,用一种特殊符号表示形参和返回值的类型
                 抽象为:
                           T add(T a,T b);  //伟大的设想,到时候用户传递的实参是什么类型,那么T就是什么类型

   2.语法规则
                   template  //C++中的关键字
                   typename  //C++中的关键字
                   template<typename T>  //声明一个模板,给这个模板取名叫做T
                   或者template<class T>  //声明一个模板,给这个模板取名叫做T
                   T add(T a,T b)  //模板函数
                   {
                           函数的源码
                  }
                  注意:模板不能共用(每个模板函数都要单独声明自己的模板),前面声明的模板,后面的函数如果还需要使用模板(要单独声明)

   3.模板函数
                 定义:只要一个函数中使用了模板,该函数就是模板函数
                 底层原理(模板的实例化):C++的编译器会依据函数调用时候传递的实参类型,去替换掉模板T的类型
      模板函数跟具体版本的函数放在一起,优先调用具体版本的函数

   4..模板类
                 定义:只要一个类中使用了模板,这个类就是模板类
                 创建对象:
                           类名<模板的类型>  对象名;
                           比如: Cat<int>  c1;


using namespace std;

//定义一个模板函数
template<typename T>  //声明一个模板,叫做T
T add(T a,T b) //表示a,b以及函数返回值类型必须是相同的
{
	cout<<"模板函数被调用了"<<endl;
	return a+b;
}

int main()
{
	int a=99;
	int b=77;
	double c=87.5;
	double d=78.3;
	
	//调用模板函数
	cout<<"a+b is: "<<add(a,b)<<endl; //模板的实例化,理解为 add(int,int)
	cout<<"c+d is: "<<add(c,d)<<endl; //模板的实例化,理解为 add(double,double)
	//error: no matching function for call to ‘add(int&, double&)’
	cout<<"a+c is: "<<add(a,c)<<endl;   //模板的实例化,理解为 add(int,double)

}
#include <iostream>

using namespace std;

//定义一个模板函数
template<typename T1,typename T2>  //声明两个模板,叫做T1和T2
T2 add(T1 a,T2 b) 
{
	cout<<"模板函数被调用了"<<endl;
	return a+b;
}

int main()
{
	int a=99;
	int b=77;
	double c=87.5;
	double d=78.3;
	
	//调用模板函数
	cout<<"a+b is: "<<add(a,b)<<endl; //模板的实例化,理解为 add(int,int)
	cout<<"c+d is: "<<add(c,d)<<endl; //模板的实例化,理解为 add(double,double)
	cout<<"a+c is: "<<add(a,c)<<endl;   //模板的实例化,理解为 add(int,double)

}

#include <iostream>
using namespace std;

template<typename T>
T  add(T a,T b)  //模板函数
{
	cout<<"版本1"<<endl;
}

template<typename T>
T  add(T a,int b)  //部分模板,部分具体
{
	cout<<"版本2"<<endl;
}
int add(int a,int b)  //具体版本的add
{
	cout<<"版本3"<<endl;
} 

int main()
{
	int a=99;
	int b=77;
	char c='@';
	double d=78.5;
	
	add(d,b);
}
#include <iostream>

using namespace std;

template<typename T>
class myarray
{
public:
	//构造函数初始化
	myarray(int _n)
	{
		n=_n;
		buf=new T[n];
	}
	//析构释放
	~myarray()
	{
		delete []buf;
	}
	//遍历数组
	void show()
	{
		int i;
		for(i=0; i<n; i++)
			cout<<"buf成员是: "<<buf[i]<<endl;
	}
	//存放数据到数组
	void putdata(T data,int i)
	{
		buf[i]=data;
	}
	//返回数组下标为i的成员
	T at(int i)
	{
		return buf[i];
	}
private:
	T *buf;
	int n;
};

int main()
{
	//int类型
	// myarray<int> array1(3);
	// array1.putdata(5,0);
	// array1.putdata(6,1);
	// array1.putdata(7,2);
	
	// array1.show();
	// cout<<"下标1的数据是: "<<array1.at(1)<<endl;
	
	//string类型
	myarray<string> array1(3);
	array1.putdata("hello",0);
	array1.putdata("gec",1);
	array1.putdata("中国人",2);
	
	array1.show();
	cout<<"下标1的数据是: "<<array1.at(1)<<endl;
}
#include <iostream>
using namespace std;

//定义一个模板类
template<typename T>
class Cat
{
public:
	Cat(T _n)
	{
		n=_n;
	}
	void show() const
	{
		cout<<"n is:"<<n<<endl;
	}
private:
	T n;
	int age;
};

int main()
{
	//创建一个猫的对象
	//错误的,模板类创建对象必须传递模板参数
	//Cat c1(5);
	
	//正确写法
	Cat<int> c1(5);
	c1.show();
	
	Cat<double> c2(8.5);
	c2.show();
	
	Cat<string> c3("gec");
	c3.show();
}
#include <iostream>
using namespace std;

//定义两个模板类
template<typename T1,typename T2>
class Cat
{
public:
	Cat(T1 _n,T2 _m)
	{
		n=_n;
		m=_m;
	}
	void show() const
	{
		cout<<"n is:"<<n<<endl;
		cout<<"m is:"<<m<<endl;
	}
private:
	T1 n;
	T2 m;
};

int main()
{
	//创建一个猫的对象
	Cat<int,double> c1(5,7.5);
	c1.show();
	
	Cat<int,int> c2(10,8);
	c2.show();
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hqb_newfarmer

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值