【贪玩巴斯】c++核心编程,你需要敲出这些程序 !(五){定义类、友元的使用、运算符重载——加号、左移、递增、赋值、关系函数调用运算符的重载} //2021-04-26

//

//  main.cpp

//  _day5

//

//  Created by AchesonD16 贪玩巴斯 on 2021/4/22.

//

 

一、定义数据实体类

/*

//知识点:

//定义你的数据实体类

class MyData()

{

//定义你的类成员

}

//被调函数

void func(MyData *p)

{

//这里写你的处理代码

}

//主函数

void mainfunc()

{

MyData data;//对象创建在栈上,本函数结束后自动退栈,无需处理

MyData *p=new MyData();//对象创建在堆上并直接赋值给指针,本函数结束前需要释放内存

func(&data);//引用实体对象的地址传递

func(p);//直接传递指针p (地址)

if (p)

{

delete p;

p=null;

 } // 释放由new创建的对象,释放前做判断,释放后将指针设置null养成好习惯。

}

*/

 

 

 

 

 

二、友元

 

//友元

/*

生活中家里有客厅(Public),有你的卧室(Private)

客厅所有来的客人都允许进去, 但是卧室是私有的,这有你本人能进去

但是,你也可以允许你的好闺蜜好基友进去。

 

在程序里,有些私有属性 也想让类外特殊的一些函数或者类进行访问,就需要用到友元技术

友元的目的就是让一个 函数 或者 类 访问另一个类中的私有成员

友元的关键字为:

friend

友元的三种实现:

全局函数做友元   friend void goodGay(Building* building1)      //  friend 后加函数全部声明

类做友元

成员函数做友元

*/

 

 

/*

//1、全局函数做友元

 

#include<iostream>

using namespace std;

 

class Building

{

    //告诉编译器 goodGay全局函数 是Building类的好朋友,可以访问类中的私有内容

    friend void goodGay(Building* building1);

    

public:

    Building()

    {

        this->m_SittingRoom = "客厅";

        this->m_BedRoom = "卧室";

    }

    

public:

    string m_SittingRoom;   //客厅

private:

    string m_BedRoom;     //卧室

};

 

 

void goodGay(Building* building1)

{

    cout << "好基友正在访问:" << building1 -> m_SittingRoom << endl;

    cout << "好基友正在访问:" << building1 -> m_BedRoom << endl;

}

 

void test1()

{

    Building b;

    goodGay(&b);

}

 

int main()

{

    test1();

    system("pause");

    return 0;

}

 

结果:

好基友正在访问:客厅

好基友正在访问:卧室

*/

 

 

/*

//2、类做友元

 

#include<iostream>

using namespace std;

 

class Building;  // 先声明类

class goodGay

{

public:

    goodGay();

    void visit();

    

private:

    Building *building1;

};

 

class Building

{

    //告诉 编译器 goodGay类是Building类的好朋友,可以访问Building类中私有的内容

    friend class goodGay;

    

public:

    Building();

    

public:

    string m_SittingRoom;  //客厅

private:

    string m_BedRoom;      //卧室

};

 

//在类外通过作用域 来调用构造函数赋初值

Building::Building()

{

    this->m_SittingRoom = "客厅";

    this->m_BedRoom = "卧室";

}

 

goodGay::goodGay()

{

    building1 = new Building;

}

 

void goodGay::visit()

{

    cout << "好基友正在访问:" << building1->m_SittingRoom << endl;

    cout << "好基友正在访问:" << building1->m_BedRoom << endl;

}

 

void test1()

{

    goodGay paidaxing;

    paidaxing.visit();

}

 

int main()

{

    test1();

    

    system("pause");

    return  0;

}

结果:

好基友正在访问:客厅

好基友正在访问:卧室

*/

 

 

 

/*

//3、成员函数做友元

 

#include<iostream>

using namespace std;

 

class Building;

class goodGay

{

public:

    goodGay();

    void visit0();  // 只让visit0函数作为Building的好朋友,可以访问Building中私有内容

    void visit1();

    

private:

    Building* building1;

};

 

class Building

{

    //告诉编译器  goodGay类中的visit成员函数  是 Building的好朋友,可访问私有内容

    friend void goodGay::visit0();

    

public:

    Building();

    

public:

    string m_SittingRoom;   //客厅

private:

    string m_BedRoom;       //卧室

};

 

Building::Building()

{

    this->m_SittingRoom = "客厅";

    this->m_BedRoom = "卧室";

}

 

goodGay::goodGay()

{

    building1 = new Building;

}

 

void goodGay::visit0()

{

    cout << "好基友正在访问:" << building1->m_SittingRoom << endl;

    cout << "好基友正在访问:" << building1->m_BedRoom << endl;

}

 

void goodGay::visit1()

{

    cout << "好基友正在访问:" << building1->m_SittingRoom << endl;

    // 错误了! 因为m_BedRoom为私有属性  cout << "好基友正在访问:" << building1->m_BedRoom << endl;

}

 

void test1()

{

    goodGay paidaxing;

    paidaxing.visit0();

    cout << "下面展示不为友元没有权限的访问结果:" << endl;

    paidaxing.visit1();

}

 

int main()

{

    test1();

    

    system("pause");

    return 0;

}

结果:

好基友正在访问:客厅

好基友正在访问:卧室

下面展示不为友元没有权限的访问结果:

好基友正在访问:客厅

*/

 

 

 

 

 

三、运算符重载

 

//运算符重载

//运算符重载概念:对已有的运算符重新进行定义,赋予其另一种功能,以适应不同的数据类型

 

1、加号运算符重载

/*

//加号运算符重载  格式: Person operator+(const Person& p)

//作用:实现两个自定义数据类型相加的运算

 

#include<iostream>

using namespace std;

 

class Person

{

public:

    Person()

    {};

    

    Person(int a,int b)

    {

        this->m_A = a;

        this->m_B = b;

    }

    //成员函数实现 + 号运算符重载

    Person operator+(const Person& p)

    {

        Person temp;

        temp.m_A = this->m_A + p.m_A;

        temp.m_B = this->m_B + p.m_B;

        return temp;

    }

    

public:

    int m_A;

    int m_B;

};

 

//全局函数实现 + 号运算符重载

//Person operator+ (const Person& p1, const Person& p2)

//{

//    Person temp(0, 0);

//    temp.m_A = p1.m_A + p2.m_A;

//    temp.m_B = p1.m_B + p2.m_B;

//    return temp;

//}

 

 

//运算符重载  可以发生函数重载

Person operator+ (const Person& p2, int val)

{

    Person temp;

    temp.m_A = p2.m_A + val;

    temp.m_B = p2.m_B + val;

    return temp;

}

 

void  test()

{

    Person p1(10, 10);

    Person p2(20, 15);

    

 

    //成员函数方式

    Person p3 = p2 + p1;  //相当于 p2.operator+(p1);

    cout << "mA:" << p3.m_A << endl << "mB:" << p3.m_B << endl;

    

    Person p4 = p3 + 10;  //相当于 operator+(p3, 10)

    cout << "mA:" << p4.m_A << endl << "mB:" << p4.m_B << endl;

}

 

int main()

{

    test();

    

    system("pause");

    return 0;

}

结果:

mA:30

mB:25

 

 

总结1:对于内置的数据类型的表达式的运算符是不可能改变的

总结2:不要滥用运算符重载

*/

 

 

 

2、左移运算符重载

/*

//左移运算符重载

//作用:可以输出自定义数据类型

 

#include<iostream>

using namespace std;

 

class Person

{

    friend ostream& operator<< (ostream& out, Person& p);  //友元

    

public:

    

    Person(int a, int b)  //有参构造

    {

        this->m_A = a;

        this->m_B = b;

    }

    

    //成员函数 实现不了  p << cout 不是我们想要的效果

    //void operator << (Person& p)

    //{}

    

private:

    int m_A;

    int m_B;

};

 

//全局函数实现左移重载

//osteram对象只能有一个

 

ostream& operator<< (ostream& out, Person& p)

{

    out << "a:" << p.m_A << " b:" << p.m_B;

    return out;

}

 

void test()

{

    Person p1(10, 20);

    cout << p1 << "  hello world" << endl; //链式编程

}

 

int main()

{

    test();

    

    system("pause");

    return 0;

}

结果:

a:10 b:20  hello world

 

总结:重载左移运算符配合友元可以实现输出自定义数据类型

*/

 

 

3、递增运算符重载

/*

//递增运算符的重载

//作用: 通过重载递增运算符,实现自己的整型数据

 

#include<iostream>

using namespace std;

 

class MyInteger

{

    friend ostream& operator << (ostream& out, MyInteger myint);

    

public:

    MyInteger()

    {

        m_Num = 0;

    }

    //前置++ 重载递增运算符

    MyInteger& operator++()

    {

        //先++

        m_Num++;

        //再返回

        return *this;

    }

    

    //后置++ //后置返回的是

    MyInteger operator++(int)

    {

        //先返回

        MyInteger temp = *this; //记录当前本身的值,然后让本身的值加1,

        m_Num++;                //但是返回的是以前的值,达到先返回后++;

        return  temp;

    }

    

private:

    int m_Num;

};

 

ostream& operator<<(ostream& out, MyInteger myint)

{

    out << myint.m_Num;

    return out;

}

 

//前置++ :先++ 再返回

void test1()

{

    MyInteger myInt;

    cout << ++myInt << endl;

    cout << myInt << endl;

}

 

//后置++ :先返回值,再++

void test2()

{

    MyInteger myInt;

    cout << myInt++ << endl;

    cout << myInt << endl;

}

 

int main()

{

    test1();

    test2();

    

    system("pause");

    return 0;

}

结果:

1

1

0

1

 

//总结:

前置递增返回 引用,后置递增返回 值。

 

*/

 

 

 

4、赋值运算符重载

 

/*

//赋值运算符重载

//c++编译器至少给一个类添加4个函数

//1、默认构造函数(无参,函数体为空)

//2、默认析构函数(无参,函数体为空)

//3、默认拷贝构造函数,对属性进行值拷贝

//4、赋值运算符 operator=, 对属性进行值拷贝

//

//如果类中有属性指向堆区,做赋值操作时也会出现深浅拷贝问题

 

#include<iostream>

using namespace std;

 

class Person

{

public:

    Person(int age)  //构造函数

    {

        //将年龄数据开辟到堆区

        m_Age = new int(age);

    }

    

    //重载赋值运算符 标准格式

    Person& operator=(Person &p)

    {

        if(m_Age != NULL)

        {

            delete m_Age;

            m_Age = NULL;

        }

        

        //编译器提供的代码是浅拷贝

        //m_Age = p.m_Age;

        

        //提供深拷贝 解决浅拷贝的问题

        m_Age = new int(*p.m_Age);

        

        //返回自身

        return *this;

    }

    

    ~Person()

    {

        if(m_Age != NULL)

        {

            delete m_Age;

            m_Age = NULL;

        }

    }

    

    //年龄的指针

    int *m_Age;

};

 

void test1()

{

    Person p1(18);

    Person p2(20);

    Person p3(30);

    p3 = p2 = p1; //赋值操作

    cout << "p1的年龄为:" << *p1.m_Age << endl;

    cout << "p2的年龄为:" << *p2.m_Age << endl;

    cout << "p3的年龄为:" << *p3.m_Age << endl;

}

 

int main()

{

    //结果1:

    test1();

    

    //结果2:

    int a = 10;

    int b = 20;

    int c = 30;

    

    c = b = a;

    cout << " a = " << a << endl;

    cout << " b = " << b << endl;

    cout << " c = " << c << endl;

    

    

}

//结果1:

//p1的年龄为:18

//p2的年龄为:18

//p3的年龄为:18

//a = 10

//b = 10

//c = 10

 

*/

 

 

 

 

5、关系运算符重载

/*

//关系运算符重载

//作用: 重载关系运算符,可以让两个自定义类型对象进行对比操作

 

#include<iostream>

using namespace std;

 

class Person

{

public:

    Person(string name, int age)

    {

        this->m_Name = name;

        this->m_Age = age;

    }

    

    bool operator==(Person& p)

    {

        if(this->m_Name == p.m_Name && this->m_Age == p.m_Age)

        {

            return true;

        }

        else

        {

            return false;

        }

    }

 

    

    bool operator!=(Person& p)

    {

        if(this->m_Name == p.m_Name && this->m_Age == p.m_Age)

        {

            return false;

        }

        else

        {

            return true;

        }

    }

    

    string m_Name;

    int m_Age;

    

};

 

void test1()

{

    //int a = 0;

    //int b = 0;

    

    Person a("孙悟空", 18);

    Person b("孙悟空", 18);

    

    if(a == b)

    {

        cout << "a和b相等" << endl;

    }

    

    if(a != b)

    {

        cout << "a和b不相等" << endl;

    }

    else

    {

        cout << "a和b相等" << endl;

    }

}

 

int main()

{

    test1();

    

    system("pause");

    return 0;

}

 

结果:

a和b相等

a和b相等

*/

 

 

 

6、函数调用运算符重载

 

/*

//函数调用运算符重载

//函数调用运算符()也可以重载

//由于重载后使用的方法非常像函数的调用,因此称为仿函数

//仿函数没有固定写法,非常灵活

 

#include<iostream>

using namespace std;

 

class MyPrint

{

public:

    //格式如下!:

    void operator()(string text)

    {

        cout << text << endl;

    }

};

 

void test1()

{

    //重载的() 操作符 也称为仿函数

    MyPrint myFunc;

    myFunc("你好!世界!");

}

 

class MyAdd

{

public:

    int operator()(int v1, int v2)

    {

        return v1 + v2;

    }

};

 

void test2()

{

    MyAdd add;

    int ret = add(10, 10);

    cout << "ret = " << ret << endl;

    

    //匿名对象调用

    cout << "MyAdd()(100, 100) = " << MyAdd()(100, 100) << endl;

}

 

int main()

{

    test1();

    test2();

    

    system("pause");

    return  0;

}

结果:

你好!世界!

ret = 20

MyAdd()(100, 100) = 200

*/

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

贪玩巴斯

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值