补知识点(this指针,友元,运算符重载)
Posted 钟钟终
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了补知识点(this指针,友元,运算符重载)相关的知识,希望对你有一定的参考价值。
this 指针
1.指向被调用的成员函数所属的对象
2.解决名称冲突 (形参与命名冲突)
this->age=age //加以区分,this指向被调用的成员函数所属的对象
3.返回对象本身用 *this
#include <iostream>
using namespace std;
class person
{
public:
int age;
person(int age)
{
this->age=age;
}
/*person addperson(person &p) //以值的方式返回
{
this->age+=p.age; //每次调用会返回新的对象(拷贝构造函数)
return *this;
}*/
person& addperson(person &p) //以引用的方式返回,返回本体
{
this->age+=p.age;
return *this;
}
};
int main()
{
person p1(20);
cout<<p1.age<<endl;
person p2(20);
p2.addperson(p1).addperson(p1).addperson(p1); //链式编程
cout<<p2.age<<endl;
return 0;
}
友元
1.全局函数做友元
#include <iostream>
using namespace std;
class person
{
friend void show(person *p);
int age;
public:
string name;
person(string name1,int age1)
{
name=name1;
age=age1;
}
};
void show(person *p)
{
cout<<"name: "<<p->name<<endl;
cout<<"age: "<<p->age<<endl;
}
int main()
{
person p("zsy",19);
show(&p);
return 0;
}
2.类做友元
目的:一个类可以访问另一个类的私有成员
垃圾代码记录下。。。
#include <iostream>
using namespace std;
class person
{
friend class visit;
int age;
public:
string name;
person(string name1,int age1)
{
name=name1;
age=age1;
}
};
class visit
{
public:
void show()
{
person p("zsy",19); //放在其他地方就不行??
cout<<"name: "<<p.name<<endl;
cout<<"age: "<<p.age<<endl;
}
};
int main()
{
visit v;
v.show();
return 0;
}
改进后代码:
#include <iostream>
using namespace std;
class person; //声明,告诉系统存在person这个类
class stu1
{
public:
stu1();
void visit();
private:
person *p; //创建person类的一个指针
};
class person
{
friend class stu1; //stu1可使用person类的变量
public:
person(string m_name,int age1);
public:
string name;
private:
int age;
};
person::person(string m_name,int age1)
{
name=m_name;
age=age1;
}
stu1::stu1()
{ //new创建什么类型的变量就返回什么类型的指针
p=new person("张三",20); //堆区创建一个对象
}
void stu1::visit()
{
cout<<"姓名: "<<p->name<<endl;
cout<<"年龄: "<<p->age<<endl;
//由于person类是stu1的友元,所以可访问私有变量
}
int main()
{
stu1 s;
s.visit();
return 0;
}
3.成员函数做友元
与类做友元类似
class person;
class stu1
{
public:
stu1();
void visit();
private:
person *p;
};
class person
{
friend void stu1::visit();
//告诉编译器,stu1的visit()函数是person类的友元函数,可以访问私有成员
public:
person(string m_name,int age1);
public:
string name;
private:
int age;
};
person::person(string m_name,int age1)
{
name=m_name;
age=age1;
}
stu1::stu1()
{
p=new person("张三",20);
}
void stu1::visit()
{
cout<<"姓名: "<<p->name<<endl;
cout<<"年龄: "<<p->age<<endl;
}
运算符重载
内置的数据类型,编译器知道之和处理;
但是两个在定义类型的相加,需要告诉编译器如何进行操作。
1.加号“+”运算符重载
#include <bits/stdc++.h>
using namespace std;
class number
{
friend number operator+ (number &n1,number &n2);
friend number operator+ (number &n1,int n);
int x,y;
public:
number(int a,int b)
{
x=a;
y=b;
}
/*number operator+ (number &n) //类内重载
{
x+=n.x;
y+=n.y;
return *this;
}*/
void display()
{
cout<<x<<" "<<y<<endl;
}
};
number operator+ (number &n1,number &n2) //全局函数重载
{
number temp(0,0);
temp.x=n1.x+n2.x;
temp.y=n1.y+n2.y;
return temp;
}
number operator+ (number &n1,int n) //运算符重载 可以发生函数重载
{
n1.x+=n;
n1.y+=n;
return n1;
}
int main()
{
number n1(5,10);
number n2(2,7);
//n1=n1+n2;
number n3=n1+n2;
n3.display();
n1=n1+3;
n1.display();
return 0;
}
2.重载左移运算符 “<<"
目的:输出自定义的对象
不能使用成员函数重载无法实现cout在左侧
因此要使用全局函数重载。
#include <bits/stdc++.h>
using namespace std;
class person
{
friend ostream &operator<< (ostream &out,person &p);
int m_a;
int m_b;
public:
person(int a,int b)
{
m_a=a;
m_b=b;
}
};
ostream &operator<< (ostream &out,person &p)
//链式输出,因此要返回out的的引用,避免调用拷贝构造函数,产生新的变量
{
out<<p.m_a<<" "<<p.m_b;
return out;
}
int main()
{
person p(12,14);
cout<<p<<endl; //输出自定义变量
return 0;
}
3.重载递增运算符
#include <bits/stdc++.h>
using namespace std;
class integer
{
friend ostream& operator<<(ostream &out,integer &n);
friend integer& operator++(integer &n);
int m_num;
public:
integer(int num)
{
m_num=num;
}
integer& operator++(int) //成员函数重载后置运算符
{
integer temp=*this;
m_num++;
return temp;
}
};
ostream& operator<<(ostream &out,integer &n) //重载输出运算符
{
out<<n.m_num;
return out;
}
integer& operator++(integer &n) //全局函数重载前置运算符
{
n.m_num++;
return n;
}
int main()
{
integer n(10);
cout<<++n<<endl;
cout<<n<<endl;
cout<<"***************区分前置、后置***************"<<endl;
integer n1(20);
cout<<n1++<<endl;
cout<<n1<<endl;
return 0;
}
4.赋值运算符重载
#include <bits/stdc++.h>
using namespace std;
class integer
{
friend ostream& operator<<(ostream &out,integer &n);
int *m_num;
public:
integer(int num)
{
m_num=new int(num);
}
integer& operator=(integer &n)
{
if(m_num!=NULL)
{
delete m_num; //删除这个地址
m_num=NULL; //使数据成员(指针)指向空
}
m_num=new int(*n.m_num);
//数据成员(指针)来维护new开辟的这片内存
return *this;
//由于this指向调用它的成员函数,因此返回的也是调用它的对象
}
/*~integer()
{
if(m_num!=NULL)
{
delete m_num;
m_num=NULL;
}
}*/
};
ostream& operator<<(ostream &out,integer &n) //重载输出运算符
{
out<<*n.m_num;
return out;
}
int main()
{
integer n1(10);
integer n2(20);
integer n3(30);
n3=n2=n1;
cout<<n3<<endl;
return 0;
}
5.关系运算符重载
…过于简单
#include <iostream>
using namespace std;
class judge
{
int m_a,m_b;
public:
judge(int a,int b)
{
m_a=a;
m_b=b;
}
bool operator==(judge &p)
{
if(m_a==p.m_a&&m_b==p.m_b)
{
return 1;
}
else
return 0;
}
};
int main()
{
judge p1(5,10);
judge p2(5,10);
judge p2(8,10);
if(p1==p2)
cout<<"两变量相等"<<endl;
else
cout<<"两变量无关"<<endl;
return 0;
}
6.函数调用运算符重载
重载的()操作符,也成为仿函数。
运用灵活!!!
#include <iostream>
using namespace std;
class myprint
{
public:
void operator()(string s)
{
cout<<s<<endl;
}
};
class myadd
{
int m_a,m_b;
public:
myadd(int a,int b)
{
m_a=a;
m_b=b;
}
int operator()()
{
return m_a+m_b;
}
};
int main()
{
myprint p;
p("zhangsan"); //函数调用运算符()
myadd p1(10,20);
int tmp=p1();
cout<<tmp<<endl;
return 0;
}
以上是关于补知识点(this指针,友元,运算符重载)的主要内容,如果未能解决你的问题,请参考以下文章
C++运算符重载中 重载为类的成员函数和重载为类的友元函数 的区别是啥?