1.引用
在平常的操作中,我们需要将一个数据的地址进行传参到函数进行功能的实现,但是如果在比较长的代码过程中,我们容易出现将数据地址错误的赋值更改,就会出现逻辑上的错误,就会非常头疼,因为通过调试来发现逻辑错误是一件很困难痛疼的事,因此我们需要一种语法来实现数据传参的同时能达到安全性---->引用
通过引用的方式,我们可以实现在传参到函数中后,编译器设定了&refb不能被修改的条件,就不会出现因地址被修改而出现的逻辑错误了。(&base就叫引用)
1.指针传参时传递地址:&base
2.引用传参时传递对象:base
总结:
1.引用是C++里的类型
2.引用类型不能被重新赋值
3.引用可以理解为是编译器维护的一个指针,但是不占任何空间(在汇编当中引用和指针的代码一样,但是编译器却限制了一些操作)
4.使用引用可以像指针那杨去访问,修改,对象的内容,但是比指针更加安全
2.友元函数
当我们定义一个类,但是里面的成员变量是私有时,但是我们却有需要访问成员变量的需求是,又或者是我们前面定义了一个类,里面的成员变量是私有的,但是我们后面定义的函数中需要访问到上面类的成员变量时,我们就需要使用友元函数来进行访问,如下:
什么情况下需要用到友元函数:
1.运算符重载的某些场合
2.两个类要共享数据时(friend + 类名)
友元函数和成员函数的区别:
1.成员函数有this指针作为参数,而友元函数没有
2.友元函数是不能被继承的,父类中声明的友元函数在子类中不能使用,就像父亲的朋友并不一会是儿子的朋友
3.运算重载
在昨天我们已经尝试了对结构体之间的比较大小,虽然可以将接受的参数定义成模板,但是在比较大小时,结构体并不能想普通类型那样简单就能实现运算,需要将各种类型的运算定义成一种模板来达到各种类型之间运算能够兼容的形式------->运算重载
定义:运算重载就是将函数重命名为运算符,并且可以实现运算符的书写来实现函数功能
格式:
在类/结构体外定义重载时的书写:
1.返回值为什么是*this
因为在*this中才是类的地址
#include<stdio.h>
class Number
{
private:
int lowValue;
int highValue;
public:
Number(int lowValue,int highValue);
void Print();
Number operator++();
Number operator--();
Number operator+(const Number& p);
Number operator-(const Number& p);
Number operator*(const Number& p);
Number operator/(const Number& p);
bool operator>(const Number& p);
bool operator<(const Number& p);
bool operator==(const Number& p);
};
Number::Number(int lowValue,int highValue)
{
this->lowValue = lowValue;
this->highValue = highValue;
}
void Number::Print()
{
printf("%d\n",lowValue);
printf("%d\n",highValue);
}
Number Number::operator++()
{
lowValue++;
highValue++;
return *this;
}
Number Number::operator--()
{
lowValue--;
highValue--;
return *this;
}
Number Number::operator+(const Number& p)
{
this->highValue = this->highValue + p.highValue;
this->lowValue = this->lowValue + p.lowValue;
return *this;
}
Number Number::operator-(const Number& p)
{
this->highValue = this->highValue - p.highValue;
this->lowValue = this->lowValue - p.lowValue;
return *this;
}
Number Number::operator*(const Number& p)
{
this->highValue = this->highValue * p.highValue;
this->lowValue = this->lowValue * p.lowValue;
return *this;
}
Number Number::operator/(const Number& p)
{
this->highValue = this->highValue / p.highValue;
this->lowValue = this->lowValue / p.lowValue;
return *this;
}
bool Number::operator>(const Number& p)
{
if(this->highValue > p.highValue)
{
return true;
}
return false;
}
bool Number::operator<(const Number& p)
{
if(this->highValue < p.highValue)
{
return true;
}
return false;
}
bool Number::operator==(const Number& p)
{
if(this->highValue == p.highValue)
{
return true;
}
return false;
}
void Test()
{
Number p(1,2),p2(3,4);
p++;
p.Print();
p--;
p.Print();
p = p+p2;
p.Print();
}
int main(int argc, char* argv[])
{
Test();
return 0;
}
4.作业
1.定义一个类,使用友元函数实现+、-、*、/、>、<、==、>=、<=(什么情况下一定要用友元函数?)
当类外面的函数需要访问到类里面的成员时
#include<stdio.h>
class Base
{
int x;
int y;
public:
Base()
{
x=1;
y=1;
}
void Print()
{
printf("%d %d\n",x,y);
}
friend Base operator+(Base& base,Base& fp);
friend Base operator-(Base& base,Base& fp);
friend Base operator*(Base& base,Base& fp);
friend Base operator/(Base& base,Base& fp);
friend bool operator>(Base& base,Base& fp);
friend bool operator<(Base& base,Base& fp);
friend bool operator<=(Base& base,Base& fp);
friend bool operator>=(Base& base,Base& fp);
friend bool operator==(Base& base,Base& fp);
};
Base operator+(Base& base,Base& fp)
{
base.x=base.x+fp.x;
base.y=base.y+fp.y;
return base;
}//+
Base operator-(Base& base,Base& fp)
{
base.x=base.x-fp.x;
base.y=base.y-fp.y;
return base;
}//-
Base operator*(Base& base,Base& fp)
{
base.x=base.x*fp.x;
base.y=base.y*fp.y;
return base;
}//*
Base operator/(Base& base,Base& fp)
{
base.x=base.x/fp.x;
base.y=base.y/fp.y;
return base;
}// /
bool operator>(Base& base,Base& fp)
{
if(base.x>fp.x)
return true;
else
return false;
}//>
bool operator<(Base& base,Base& fp)
{
if(base.x<fp.x)
return true;
else
return false;
}//<
bool operator>=(Base& base,Base& fp)
{
if(base.x>=fp.x)
return true;
else
return false;
}//>=
bool operator<=(Base& base,Base& fp)
{
if(base.x<=fp.x)
return true;
else
return false;
}//<=
bool operator==(Base& base,Base& fp)
{
if(base.x==fp.x)
return true;
else
return false;
}//==
int main()
{
Base base;
Base base1;
base=base+base1;
base.Print();
base=base*base1;
base.Print();
base=base*base1;
base.Print();
return 0;
}
2.从反汇编的角度说一下引用和指针的区别
从汇编代码来看,引用和指针没有任何区别
但是对于编译器而言,引用时编译器认为引用对象的地址不可修改
但是没有用任何代码和空间来说明这一条件