C++ Day7类与对象 中

一、对象特性

1.1 空指针访问成员函数

  • 应使用条件判断防止因空指针访问成员属性出错。
#include<iostream>
using namespace std;
class student
{
    int a=0;
public:
    void print()
    {
        cout<<"不报错"<<endl;
    }
    void show()
    {
        // if(this==NULL)  //防止出错
        // {
        //     return;
        // }
        cout<<"报错"<<a<<endl;//等价于 this->a
    }
};
int main()
{
    student *p=NULL;
    p->print();
    //p->show();会报错因为空指针没有确定的对象访问不到属性,无中生有
    system("pause");
}

1.2 const 修饰成员函数

  • 常函数:成员函数加const后 void getname() const{};
  • 常函数不可以修改成员属性相当于对于指针常量前面加上const:const student * const this;//值和指向都不能更改。除了一种情况:在成员属性前加关键字mutable:mutable int a;该值可改。
  • 常对象:实例化对象时加上const;
  • 常对象只能调用常函数,不能修改属性除了在成员属性前加关键字mutable:mutable int a;可以修改属性

二、友元

  • 定义:让类外特殊的一些函数或者类进行访问另一个类中的私有成员
  • 关键字 friend

2.1 全局函数做友元

#include<iostream>
using namespace std;
class student
{
friend void find(student &student);//作为友元访问私有成员。
private:
    int name=0;
};
void find(student &student)//全局函数
{
    cout<<student.name<<endl;
}
int main()
{
    student s2;
    find(s2);
    system("pause");
}

2.2 友元类

#include<iostream>
using namespace std;
class student
{
	friend class teacher;//友元类
	private:
    	int name=0;
};
class teacher
{
    public:
        student s1;
    void getname()
    {       
       cout<<s1.name<<endl;//访问私有成员;
    }
};

2.3成员函数做友元

#include<iostream>
using namespace std;
class student;
class teacher
{
    public:
    void getname();
    void setname();
};
class student
{
friend void teacher::getname();//成员函数做友元
private:
    int name=0;
};
void teacher::getname()
{
    student s;
    cout<<s.name<<endl;
}
int main()
{
    teacher t;
    t.getname();
    system("pause");
}
  • 访问的类应写在在被访问类之前,应写外部函数不然容易报错。

三、运算符重载

  • 重新定义已有的运算符,实现另一种功能(自定义的数据类型)

3.1加号

  • 实现两个自定义数据类型相加的运算
  • 成员函数本质:s2=s.operator+(s1);
  • 全局函数本质:s2=operator+(s,s1);
  • 运算符重载可以实现函数的重载
class student
{
public:
    int age=10;
    student(int age)
    {
        this->age=age;
    }
    // student operator+(student &s1)//成员函数实现+号重载
    // {
    //     student temp=0;
    //     temp.age=this->age+s1.age;
    //     return temp;
    // }
};
student operator+(student &s,student &s1)//全局函数实现加号重载
{
    student temp=0;
    temp.age=s.age+s1.age;
    return temp;
}
int main()
{
    student s(10);
    student s1=20;
    student s2=s+s1;//自定义数据类型相加
    cout<<s.age<<endl;
    cout<<s1.age<<endl;
    cout<<s2.age<<endl;
    system("pause");
}

3.2左移(输出)

  • 实现直接输出对象属性。
  • 不用成员函数重载左移运算符,不能实现变量在右边。
  • 重载返回值为ostream实现链式编程,实现追加输出。
  • 使用友元输出私有成员属性。

class student
{
public:
    int age=10;
    char *name="张三";
    student(int age)
    {
        this->age=age;
    }
};
ostream& operator<<(ostream &cout,student &p)
{
    cout<<p.name<<endl<<p.age<<endl;
    return cout;
}

int main()
{
    student s(10);
    cout<<s<<endl;
    system("pause");
}

3.3递增

  • 前置递增返回引用:实现一直对一个数据进行递增操作
  • 后置递增返回值
  • 使用占为参数区分前置和后期递增,后置递增operator++(int){};

3.4赋值

  • C++编译器至少给一个类添加四个函数:
  • 默认构造函数
  • 默认析构函数
  • 默认拷贝函数
  • 赋值运算符 operator=,进行属性值拷贝。
  • 解决浅拷贝重复释放堆区内存
  • 返回值为自身(返回*this 引用)

class student
{
public:
    int *num;
    student(int age)
    {
        num=new int(age);//指针维护堆区
    }
    student& operator=(student &s)
    {
        if(num!=NULL)
        {
            delete num;
            num=NULL;
        } 
        num=new int(*s.num);//深拷贝
        return *this;
    }
};
ostream& operator<<(ostream &cout,student &p)
{
    cout<<*p.num<<endl;
    return cout;
}
int main()
{
    student s(10);
    student s1=20;
    s1=s;
    cout<<s1<<endl;
    system("pause");
}

3.5函数调用运算符

  • 调用运算符()也可重载
  • 仿函数。
  • 无固定写法。
class student
{
public:
    int age;
    student(int age)
    {
    }
    void operator()(char * s)
    {
        cout<<s<<endl;
    }
};
int main()
{
    student s(10);
    s("1234");
    system("pause");
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值