C++ ———— 3(友元+运算符重载)

一、限制构造

构造函数在类的非public区域,称为限制构造函数,如果一个类的构造函数是限制构造,那么就不能通过该类直接实例化对象,只能通过类的静态成员函数或者友元函数去实例化对象。

二、友元

友元:可以打破类的权限限制,利用友元可以访问private和protected权限的成员

​ 类实现了数据的隐藏与封装,类的数据成员一般定义为私有成员,仅能通过类的成员函数才能读写。如果数据成员定义为公共的,则又破坏了封装性。但是某些情况下,需要频繁读写类的数据成员,特别是在对某些成员函数多次调用时,由于参数传递、类型检查和安全性检查等都需要时间开销肖,而影响程序的运行效率。

  • 友元的关键字:friend
  • 友元:不是类的成员,没有this指针

分类:

  • 友元函数
  • 友元类
  • 友元成员函数

1.友元函数

一个函数fun是一个类A的友元,我们就称fun是A的友元函数

声明位置:友元函数可以在类内的任何位置声明,也可以在类外声明,不属于类

格式:

friend void func(Demo &obj)		//友元函数例子
{
    cout << obj.val << endl;
}

2. 友元类

一个类A是另一个类B的友元类,那么此时A类的所有成员都可以访问类B

3.友元成员函数

有一个类A它里面有个成员函数fun是类B的友元,此时我们就称fun是友元成员函数

三、运算符重载

函数可以重载,运算符也可以重载

一般形式:

返回值类型	operator运算符(参数)
{
    //函数体
}

不能被重载的运算符:

?: 			//三目运算符
sizeof		//去大小运算符
::			//名字空间符
'.' '.*'	//对象指针等
,			//逗号一般不建议重载,即使要重载,也必须是类类型

运算符重载可以使用的方法:

  • 成员函数重载
  • 友元函数重载
  • 普通函数重载

练习:

重载 ! 判断顺序表是否为空

/*===============================================
*   文件名称:eg3_chongzai.cpp
*   创 建 者:青木莲华
*   创建日期:2025年08月28日
*   描    述:
================================================*/
#include <iostream>
using namespace std;

class A
{
    public:
        A(int max)
        {
            p = new int[max];
            this-> max = max;
            len = 0;
        }
        ~A()
        {
            if(p != nullptr)
            {
                delete p;
                p = nullptr;
            }
            len = 0;
            max = 0;
        }
    void insert(int num)
    {
        if(len+1 >= max)
            return;
        else
        {
            p[len] = num;
            len++;
        }
    }

    bool operator!()
    {
        return len == 0 ? true : false;
    }
    private:
        int *p;
        int len;
        int max;
};


int main()
{
    
    A a(10);
    
    !a ? cout << "obj is null" << endl : cout << "obj not null" << endl;
    
    a.insert(10);

    !a ? cout << "obj is null" << endl : cout << "obj not null" << endl;
    return 0;
}

四、作业

运算符重载——重载顺序表类的 += 、+ 等运算符

源码

/*===============================================
*   文件名称:List.cpp
*   创 建 者:青木莲华
*   创建日期:2025年08月28日
*   描    述:完善顺序表类,实现=、+=的重载。
================================================*/
#include <iostream>
using namespace std;


class List
{
    public:
        //无参构造
        List(){}
        //有参构造
        List(int size)
        {
            this->size = size;
            p = new int[size];
            index = 0;
        }
        //拷贝函数
        List(List &list)
        {
        
            cout << "copy" << endl;
            //1.拷贝最大元素个数
            size = list.size;
            //2.拷贝当前元素个数
            index = list.index;
            //开辟新数组空间
            p = new int[size];
            //逐个拷贝数组
            for(int i = 0 ; i < index ; i++)
            {
                p[i] = list.p[i];
            }
        }
        //插入新元素
        void insert(int num)
        {
            //1.判满
            if(index+1 >= size)
                return;
            //2.插入元素
            p[index] = num;
            //3.修改index
            index++;
        }
        //遍历函数
        void show()
        {
            for(int i = 0 ; i < index ; i++)
            {
                cout << p[i] << " ";
            }
            cout << endl;
        }
        //'+'运算符重载
        List operator+(const List &list)
        {   
            //1.实例化一个中间对象  this + list
            List temp(this->size + list.size);
            temp.index = index + list.index;
            //2.拷贝 this 数组的所有元素
            for(int i = 0 ; i < index ; i++)
                temp.p[i] = p[i];
            //3.拷贝 list 数组的所有元素
            for(int i = 0 ; i < list.index ; i++)
                temp.p[index + i] = list.p[i];
            //4.返回中间对象
            return temp;
        }
        //'+='运算符重载 += obj
        void operator+=(const List &list)
        {
            //1.定义临时数组
            int *temp = new int[size + list.size];
            //2.拷贝数组内容 this
            for(int i = 0 ; i < index ; i++)
                temp[i] = p[i];
            for(int i = 0 ; i < list.index ; i++)
                temp[index + i] = list.p[i];
            //3.拷贝index
            index += list.index;
            //4.拷贝size
            size += list.size;

            //5.删除旧数组
            delete[] p;
            //6.改变p指向到temp;
            p = temp;
        }
        //'+='重载 += 常量
        void operator+=(const int num)
        {
            //判满
            if(index+1 >= size)
                return;
            p[index] = num;
            index++;
        }
    private:
        int *p;         //顺序表指针,指向数组
        int size;       //顺序表最大元素个数
        int index;      //顺序表当前元素个数
    
};



int main(int argc, char *argv[])
{  
    cout << "-------a------" << endl;
    List a(10);
    a.insert(11);
    a.insert(22);
    a.insert(33);
    a.insert(44);
    a.show();
    cout << "-------b------" << endl;
    List b(10);
    b.insert(55);
    b.insert(66);
    b.insert(77);
    b.insert(88);
    b.show();
    cout << "------c = a + b------" << endl;
    List c;
    c = a + b;
    c.show();
    cout << "------a += b------" << endl;
    a += b;
    a.show();
    cout << "------a += 常数------" << endl;
    a += 311;
    a.show();
    return 0;
}

运行截图

alt