0
点赞
收藏
分享

微信扫一扫

代码生成器实现

Mhhao 2023-06-12 阅读 107

在这里插入图片描述

文章目录

🌍1. 默认成员函数

image-20230611234423079

🗾2. 构造函数

class Date
{
public:
	void Init(int year, int month, int day)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	void Print()
	{
		cout << _year << " " << _month << " " << _day << endl;

	}
private:
	int _year;
	int _month;
	int _day;
};
int main()
{
	Date d1;
	d1.Init(2023, 6, 5);
	d1.Print();
	Date d2;
	d2.Init(2023, 6, 5);
	d2.Print();
	return 0;
}

对于这个Date类,我们使用Init方法来给对象设置初始,但是每次都需要手动设置,如果对象一旦多了,麻烦不说,还有可能会忘记。C++祖师爷可能被困扰过,于是在C++中引入了构造函数

🧭2.1 概念

构造函数是一个特殊的成员函数,用于在创建对象时进行初始化操作。构造函数的名称与类名相同,并且没有返回类型(包括void)。它在对象被创建时自动调用,用于初始化对象的成员变量和执行其他必要的设置。

🧭2.2 特性

构造函数具有以下特点:

  1. 构造函数名与类名相同:构造函数的名称必须与其所属类的名称完全相同,包括大小写。

  2. 构造函数没有返回类型:与其他函数不同,构造函数没有显式的返回类型,包括void。它们在对象创建时自动调用,无需显式调用。

  3. 构造函数在对象创建时被调用:当使用类的对象声明时,构造函数会自动调用,为对象分配内存并初始化其成员变量。

    2

  4. 构造函数可以重载:一个类可以有多个构造函数,它们可以具有不同的参数列表(重载),以便在创建对象时提供不同的初始化选项。

    class Date
    {
    public:
    	//无参数
    	Date()
    	{
    		;
    	}
    	//带参数
    	Date(int year, int month, int day)
    	{
    		_year = year;
    		_month = month;
    		_day = day;
    	}
    	void Print()
    	{
    		cout << _year << " " << _month << " " << _day << endl;
    	}
    private:
    	int _year;
    	int _month;	
    	int _day;
    };
    int main()
    {
    	Date d1;
    	Date d2(2023, 6, 5);
    	d1.Print();
    	d2.Print();
    }
    
  5. 默认构造函数:如果没有定义构造函数,编译器会自动为类生成一个默认构造函数。默认构造函数没有参数,并执行默认的初始化操作。

    class Date
    {
    public:
    	void Print()
    	{
    		cout << _year << " " << _month << " " << _day << endl;
    	}
    private:
    	int _year;
    	int _month;
    	int _day;
    };
    int main()
    {
    	Date d1;
    	d1.Print();
    }
    

    运行这段代码,我们发现默认初始化的是随机值。

    image-20230605131947422

    这其实是属于C++的一个小缺陷。

  6. 无参全缺省的构造函数都是属于默认构造函数,因为它们在对象创建时提供了默认的初始化方式。无参的构造函数适用于不需要任何参数的初始化场景,而全缺省的构造函数适用于所有成员变量都具有默认值的情况。他们都不需要传参。
    无参构造函数、全缺省构造函数、编译器默认生成的构造函数,都属于默认构造函数,他们有且只能有一个。

    image-20230605141217308

🌋3. 析构函数

有了自动初始化,那自然是少不了销毁的,这两兄弟一般都是配套的。

🗻3.1 概念

析构函数是一种特殊的成员函数,它的功能与构造函数功能相反,用于在对象销毁时进行清理和释放资源的操作。析构函数的名称与类名相同前面加上波浪号~,没有参数和返回类型(包括void)。它在对象被销毁时自动调用,用于执行必要的清理操作。

🗻3.2 特性

  1. 析构函数的名称与类名相同:析构函数的名称必须与其所属类的名称完全相同,并在前面加上波浪号~,包括大小写。

  2. 析构函数没有返回类型:与其他函数不同,析构函数没有显式的返回类型,包括void。它们在对象销毁时自动调用,无需显式调用。

  3. 仅能有一个析构函数:一个类只能有一个析构函数。它不允许重载多个析构函数

  4. 析构函数在对象销毁时被调用:当对象的生命周期结束、超出作用域或显式删除对象时,析构函数会自动调用。它用于清理对象所占用的资源。

    3

  5. 自定义析构函数:如果不定义析构函数,编译器会生成一个默认的析构函数,执行默认的清理操作。但如果需要执行特定的清理操作或释放动态分配的资源,可以自定义析构函数(类中没有申请资源时,析构函数可以不写;有资源申请时,一定要写,否则会造成资源泄露)。

🪂4. 拷贝构造函数

Ctrl C(复制)和Ctrl v(粘贴)是我们十分常用的两个快捷键,而在C++中,有一个类的默认成员函数,也可完成对象的拷贝。

🚡4.1 概念

拷贝构造函数是一种特殊的构造函数,用于创建一个对象时,使用同一类的另一个对象的值进行初始化。拷贝构造函数的主要目的是创建一个新的对象,并将已存在对象的值复制到新对象中。

🚡4.2 特性

  1. .拷贝构造函数是构造函数的一个重载形式

  2. 拷贝构造函数的参数是对同一类的对象的引用,它用于指定要拷贝的对象。通常使用const关键字确保被拷贝的对象在拷贝过程中不会被修改。

  3. 默认情况下,如果没有为类定义拷贝构造函数,编译器会生成一个默认的拷贝构造函数,该函数会执行逐个成员变量的复制操作。这种操作方式叫做浅拷贝

🛸5. 赋值运算符

🛎5.1 运算符重载

C++中,内置类型可以直接比较,但是对于自定义类型,想要比较,需要我们自己写出对应的方法。

class Date
{
public:
	Date(int year = 2023, int month = 1, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	bool Less(const Date& d)
	{
		if (_year < d._year)
		{
			return true;
		}
		else if (_year == d._year && _month < d._month)
			return true;
		else if (_year == d._year && _month == d._month && _day < d._day)
			return true;
		else if (_year == d._year && _month == d._month && _day == d._day)
			exit(-1);

		return false;
	}
private:
	int _year;
	int _month;
	int _day;
};
int main()
{
	//内置类型
	int a = -1;
	int b = 1;
	cout << (a > b) << endl;

	//内置类型
	Date d1(2023,6,7);
	Date d2(2023, 6, 6);
	cout << d1.Less(d2) << endl;
	return 0;
}

这种方式显然不是很直白,于是C++引入了运算符重载:在类中重新定义已有的运算符,使其能够对类的对象进行操作

运算符重载函数的命名形式为 operator<运算符>,例如这里比较是否小于operator<

class Date
{
    bool operator<(const Date& d)
    {
    //...
    }
	//...
}
int main()
{
    //...
    Date d1(2023,6,7);
	Date d2(2023, 6, 6);
    //"<<"有优先级高于"<",所以这里要加上括号
    cout << (d1<d2) << endl;
    return 0;
}

🛎5.2 赋值运算符重载

前面所了解的拷贝构造函数,是对于一个对象去初始化创建另一个对象。而赋值运算符,用于已存在的两个对象之间的赋值。

拷贝构造的本质是一个构造函数,而赋值运算符本质上是一个运算符重载

class Date
{
public:
	Date(int year = 2023, int month = 1, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	//拷贝构造
	Date(const Date& d)
	{
		cout << "Date(const Date& d)" << endl;
		_year = d._year;
		_month = d._month;
		_day = d._day;
	}
	//运算符重载
	Date& operator=(const Date& d)
	{
		if (this != &d)
		{
			_year = d._year;
			_month = d._month;
			_day = d._day;
		}
		return *this;
	}
private:
	int _year;
	int _month;
	int _day;
};
int main()
{
	Date d1(2023, 6, 7);
    // 初始化 -- 构造函数
    Date dd1(d1);
	Date d2, d3, d4;
    // 赋值 -- 运算符重载
	d2 = d1;
	d4 = d3 = d2;
}
  • 重载的赋值运算符函数通常返回一个引用,以支持链式赋值操作,并允许连续赋值。
  • 在重载函数中进行自赋值检查。image-20230607171648169
  • 赋值运算符是一个默认成员函数,在没有显式定义的时候编译器会默认生成一个赋值运算符函数。默认赋值运算符执行逐个成员变量的赋值操作,对于指针成员变量,也是执行浅拷贝。所以如果有指针类型的成员,需要我们自己显式定义。
  • 重载赋值运算符只能重载类的成员函数,这是因为赋值运算符的操作数包括被赋值对象和右侧的对象。重载为类的成员函数时,左侧的对象将被隐式地作为调用对象,而右侧的对象则作为函数参数传递。

🛎5.3 前置++与后置++

class Date
{
public:
	//构造函数
	Date(int year = 2023, int month = 1, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	//前置++
	Date& operator++()
    {
        *this += 1;
		return *this;
    }
	//后置++
	Date operator++(int)
    {
        Date tmp(*this);
		tmp += 1;
		return tmp;
    }

private:
	int _year;
	int _month;
	int _day;
};

由于前置++和后置++的运算符都是++,为了以示区分,C++在后置++重载时加入了一个int类型的参数,不过是使用这个函数的时候,不需要传递,编译器回自动判断(前置–、后置–也是同理)。

⌛6. const成员

在C++中,const成员是指在类中声明为const的成员变量成员函数

  • const成员变量:在类中声明为const的成员变量。它们必须在类的构造函数初始化列表中进行初始化,并且不能在类的任何成员函数中修改。const成员变量可以是基本数据类型(例如int、float等)或自定义类型。const成员变量在对象创建时就被初始化,并且在对象的整个生命周期中保持不变。

  • const成员函数:const修饰类成员函数,实际修饰该成员函数隐含的this指针,表明在该成员函数中不能对类的任何成员进行修改。const成员函数通过在函数声明的末尾加上const关键字来标识。

    image-20230611233605466

    const成员函数可以重载非const成员函数,但非const成员函数不能重载const成员函数。这是因为权限可以被缩小,但是不能被放大。

    如果我们设置函数的时候,该函数不想改变成员变量,我们就可以使用const来修饰,这可以使我们的代码更加健壮。

7. 取地址和const取地址操作符重载

这两个不常用,一般不会重新定义,编译器会默认生成。

class Date
{ 
public :
 Date* operator&()
 {
 return this ;
     }
 const Date* operator&()const
 {
 return this ;
 }
private :
 int _year ; 
 int _month ; 
 int _day ; 
};

本篇主要介绍了C++的几个默认成员函数,可以把他们理解为C++的“贵族”,因为他们都是祖师爷钦点的。
那么本期的分享就到这里啦,我们下期再见,如果还有下期的话。

举报

相关推荐

0 条评论