• 类和对象——默认成员函数



    默认成员函数

    构造函数

    构造函数并不是创建一个函数,它是一种特殊的函数,给对象初始化用的。
    构造函数的形式:

    类名(参数)
    {};
    
    • 1
    • 2

    构造函数也可以重构,构造函数一般写在类里面实现形成内联函数。
    当没有自己写构造函数的时候,会调用默认的构造函数,默认的构造函数只对自定义类型进行处理(调用它的构造函数),对内置类型不做处理。
    内置类型:int double char 指针等等
    自定义类型:类 等等。
    默认构造函数:全缺省,无参,自动生成的默认构造函数
    因为不对内置类型处理,所以C++11又进行了弥补,在类的成员又加了一个默认值。

    析构函数

    析构函数的形式:

    ~类名()
    {};
    
    • 1
    • 2

    析构函数是释放类成员的资源。不是销毁对象。
    析构函数可以自己写,当没有自己实现的时候会调用默认析构函数,默认析构函数对内置类型不做处理,对自定义类型会调用它的析构函数。
    析构的顺序是先构造的后析构,后构造的先析构,局部先析构,全局/静态后析构。

    拷贝构造函数

    拷贝构造函数的形式:

    类名(const类名&对象)
    {};
    
    • 1
    • 2

    如果你创建的对象想直接是另一个对象的值,就可以使用拷贝构造

    class Date
    {
    public:
    	Date(int year = 1, int month = 1, int day = 1)
    	{
    		_year = year;
    		_month = month;
    		_day = day;
    	}
    	Date(const Date& d)
    	{
    		_year = d._year;
    		_month = d._month;
    		_day = d._day;
    
    	}
    private:
    	int _year;
    	int _month;
    	int _day;
    };
    
    int main()
    {
    	Date a(2022, 8, 11);
    	Date b(a);
    	Date c = a;
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    第26,27行的是同一个意思,都是拷贝构造,不能把第27个看作是赋值。
    关于为什么拷贝构造函数的参数是引用呢?
    是为了放在死拷贝。如果是传值拷贝,在传参的时候就要拷贝,然后就业调用这个函数,调用这个函数又需要传值拷贝,最后还是要调用这个函数…无穷无尽。而传引用就避免了这个情况。
    如果没有自己写拷贝构造函数,会调用默认构造函数,默认构造函数对内置类型进行值拷贝,对自定义类型会调用它的拷贝构造函数。

    运算符重载

    让对象也可以直接运用运算符,
    运算符重载的形式:

    返回类型operator运算符(参数)
    {};
    
    • 1
    • 2

    .* :: sizeof ?: . 这5个运算符不能重载

    赋值运算符重载

    以日期类为例

    	Date& operator=(const Date& d)
    	{
    		_year = d._year;
    		_month = d._month;
    		_day = d._day;
            
            return *this;
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    弄返回值是为了应对多次赋值的情况,引用左返回值和参数的原因是避免拷贝构造。
    即使没有显式实现赋值运算符重载,也会生成默认的,其和拷贝构造一样,内置类型值拷贝,自定义类型调用它的赋值重载。

    前置++/后置++重载

    前置后置++怎么实现呢?
    前置++,无参数
    后置++,有一个int参数,只是为了去吧,没有什么实际意义。

        //前置
        Date& operator++()
    	{
    		_day++;
    		return *this;
    	}
        //后置
    	Date operator++(int)
    	{
    		Date ret = *this;
    		_day++;
    		return ret;
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    const成员

    我们知道const修饰的不能改变,当const修饰的对象时,该对象的地址的类型是const 类*,而this指针的类型是类* const,会导致类型不匹配,所以此时要在类的成员函数后面加上一个const
    例如日期类:

    class Date
    {
    public:
        bool operator==(const Date& d)
        {
            return _year == d._year && _month == d._month && _day == d._day;
        }
    private:
    	int _year;
    	int _month;
    	int _day;
    };
    int main()
    {
    	Date a;
    	const Date b;
    	b == a;//这里就会报错
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    因为此时传过去的类型是const Date* ,而this的类型是Date* const
    这样处理就可以解决这种问题了bool operator==(const Date& d)const
    只要是不改变this指针指向的内容都可以加上const。

    &取地址操作符重载

    这种操作符默认会生成,不需要自己写

    	Date* operator&()
    	{
    		return this;
    	}
    	const Date* operator&()const
    	{
    		return this;
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
  • 相关阅读:
    Java竞赛快速输入输出,防止读取数据过慢导致超时
    LeetCode --- 1413. Minimum Value to Get Positive Step by Step Sum 解题报告
    矩阵错题本
    盘点Win前端开发下常用的软件
    Linux系统环境下项目部署
    链表面试题-刷题
    万字长文:我眼中区块链各赛道正在演进的技术趋势
    什么是交互设计?大神总结
    软件‘小程序‘前台开发软件定制的知识|app网站搭建
    Bert不完全手册7. 为Bert注入知识的力量 Baidu-ERNIE & THU-ERNIE & KBert
  • 原文地址:https://blog.csdn.net/m0_60598323/article/details/126311540