补知识点(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++运算符重载中 重载为类的成员函数和重载为类的友元函数 的区别是啥?

cpp►运算符重载与友元friend

从一个二级题来看成员函数重载运算符和友元函数重载运算符

C++笔记--面向对象(OOP)编程基础--操作符重载及友元

运算符重载和友元函数

C++友元与运算符重载结合友元