友元
=========================================
1.作用
前面学习的知识点都无法使用其它类的私有成员
C++提供了一种机制,让一个函数或者一个类可以使用其它类的私有成员
2.语法规则
友元分为两种:
第一种:友元函数
第二种:友元类
2.1 友元函数
friend 返回值 函数名字(形参); //声明友元函数
2.2 友元类
friend class 类名;
友元类的特点
特点一:友元类是单向,A是B的友元,但是你不能得出结论B是A的友元
特点二:友元不能传递,A是B的友元,B是C的友元,不能得出结论A是C的友元
特点三:友元不能继承,A是B的友元,A的子类不一定是B的友元
class Animal
{
friend class Cat;
}
class Cat
{
void fun(Animal &other) //私交甚好
{
other.私有成员变量;
}
}
class 波斯猫:public Cat
{
void otherfun(Animal &other)
{
other.私有成员
}
}
int main()
{
波斯猫 对象;
对象.fun(Animal对象的引用); //偷换概念
}
2.3 友元的缺点
破坏了类的封装性
模板(泛型编程)
=========================================
1.引入模板
前面学习过函数重载
int add(int,int)
double add(double,double)
double add(int,double)
函数重载很啰嗦--》我要写很多个版本
老外优化了--》三个版本的add仅仅参数类型不同--》我可不可以用一个"变量"(模板)替换掉参数类型--》参数的类型抽象化
干脆把add定义成 T add(T a,T b) //此时函数的返回值类型是T,参数类型也是T
模板:就是用来把参数,返回值的类型做一个抽象,用模板来替换参数,返回值的类型
泛型编程:泛型(通用类型),如果程序员在写代码的时候使用了通用类型(模板),那么我们就说这个程序员采用了泛型编程技术
2.语法规则
模板分为两种:
无论是模板函数还是模板类,都不可以重复使用同一个模板声明
模板声明不能共用(每个模板函数/模板类都要单独声明自己的模板)
第一种:模板函数--》只要一个函数使用了模板,它就是模板函数
template<typename T> //声明一个模板,模板的名字叫做T
一般我们习惯把模板的名字叫做T(多个模板T1,T2,T3......)
T add(T a,T b) //定义了一个模板函数
{
return a+b;
}
写法一:只使用一个模板
template<typename T> //声明一个模板,模板的名字叫做T
T add(T a,T b) //定义了一个模板函数
{
return a+b;
}
此时a和b的类型必须一样
写法二:使用了多个模板
template<typename T1,typename T2> //声明两个模板,模板的名字分别叫做T1,T2
T1 add(T1 a,T2 b) //定义了一个模板函数
{
return a+b;
}
此时a和b的类型可以一样,也可以不一样
写法三:一部分用了模板,还有一部分具体类型(部分使用模板)
template<typename T> //声明一个模板,模板的名字叫做T
T add(T a,int b) //定义了一个模板函数
{
return a+b;
}
第二种:模板类--》只要一个类使用了模板,这个类就是模板类
template<typename T> //声明一个模板,模板的名字叫做T
class 类名
{
private:
T n;
T m;
};
使用模板类
类名<具体类型名字> 对象名;
例如:Base<int> b(5); //Base这个类只有一个模板,int表示你的模板T就是int类型
Array<char,int> a1; //Array这个类有两个模板
注意:typename换成class是等价的 尽量少增加新的关键字
class Cat struct Cat
{ {
} }
struct定义类,如果你没有写任何权限修饰符,默认都是公有的
class定义类,如果你没有写任何权限修饰符,默认都是私有的
3.模板的原理
模板函数/模板类: 编译器依据实参的类型,去实例化模板的类型
4.模板函数跟具体版本的函数放在一起
问题一:会不会有冲突??
不会
问题二:如果没有冲突,编译器会优先选择谁?
优先选择具体版本的函数
练习
=========================================
1.通过友元函数去修改Cat类对象的年龄,体重属性
通过友元函数去获取Cat类对象的年龄,体重属性
2.验证友元类的三个特点
3.分别使用模板函数写法二和写法三
定义一个模板函数,可以求所有基本数据类型的平方