【C++】——类和对象(中)

07-17 1752阅读

文章目录

  • 类的默认成员函数
  • 构造函数
  • 析构函数
  • 拷贝构造函数
  • 赋值运算符重载
    • 运算符重载
    • const成员函数

      类的默认成员函数

      在C++中,类(class)可以拥有多种成员函数,其中一些成员函数在类定义中没有显式声明时,编译器会隐式地为该类生成。这些由编译器自动生成的成员函数被称为默认成员函数(也称为特殊成员函数)。它们包括:

      1. 默认构造函数(Default Constructor)
      2. 析构函数(Destructor)
      3. 拷贝构造函数(Copy Constructor
      4. 拷贝赋值运算符(Copy Assignment Operator)
      5. 移动构造函数(Move Constructor) 和 移动赋值运算符(Move Assignment Operator),这是C+11以后引入的,比较复杂,这里就不介绍,重点将前4个。

      构造函数

      特征:

      【C++】——类和对象(中)

      1. 函数名和类名相同
      2. 无返回值
      3. 对象实例化时编译器自动调用对应的构造函数。
      4. 构造函数可以重载。
      5. 如果类中没有显式定义构造函数,则C++编译器会自动生成一个无参的默认构造函数,一旦

        用户显式定义编译器将不再生成。

      class Data
      {
      public:
      	//1.无参构造函数
      	/*Data()
      	{
      		int _year = 1;
      		int _month = 1;
      		int _day = 1;
      	}*/
      	
      	//2.带参构造函数
      	//Date(int year, int month, int day)
      	//{
      	// 	_year = year;
      	//	_month = month;
      	//	_day = day;
      	//}
      	//3.全缺省构造函数
      	//Date(int year = 1, int month = 1, int day = 1)
      	//{
      	//	_year = year;
      	//	_month = month;
      	//	_day = day;
      	//}
      private:
      	int _year;
      	int _month;
      	int _day;
      };
      int main()
      {
      	Data d1;
      	Data d2(2024,7,15);
      	Data d3(2024);
      	return 0;
      }
      

      前面我们说过:

      “如果没有为类定义任何构造函数,编译器会生成一个默认构造函数。这个构造函数不接受任何参数,并且只进行成员变量的默认初始化(对于内置类型不做任何操作,对于类类型调用其默认构造函数)。如果类中定义了任何构造函数(包括带参数的构造函数),编译器就不会自动生成默认构造函数。”所以,无参构造函数和全缺省构造函数也是默认构造函数,因为这两种构造函数都可以不用传参。这三种默认构造只能存在一个,不能同时存在。

      总结:不传实参就可以调用的构造就叫默认构造。

      析构函数

      析构函数和构造函数功能相反,析构函数不是对对象本身的销毁,而是对对象中资源的清理工作。

      如果没有资源需要释放,就不需要析构函数了。

      特征:

      1. 析构函数名是在类名前加上字符 ~。
      2. . 无参数无返回值类型。
      3. 一个类只能有一个析构函数。若未显式定义,系统会自动生成默认的析构函数。注意:析构函数不能重载
      4. 对象生命周期结束时,C++编译系统系统自动调用析构函数。
      5. 跟构造函数类似,我们不写编译器自动生成的析构函数对内置类型成员不做处理,自定义类型成员会调用他的析构函数。
      6. 如果类没有申请资源,析构可以不用写。如果没有写析构,也会自动调用析构函数。
      7. 如果有资源申请,一定要写析构函数,否则会造成内存泄漏。
      #include
      using namespace std;
      typedef int STDataType;
      class Stack
      {
      public:
      	Stack(int n = 4)
      	{
      		_a = (STDataType*)malloc(sizeof(STDataType) * n);
      		if (nullptr == _a)
      		{
      			perror("malloc申请空间失败");
      			return;
      		}
      		_capacity = n;
      		_top = 0;
      	}
      	// ...
      	~Stack()
      	{
      		free(_a);
      		_a = nullptr;
      		_top = _capacity = 0;
      	}
      private:
      	STDataType* _a;
      	size_t _capacity;
      	size_t _top;
      };
      // 两个Stack实现队列
      class MyQueue
      {
      public:
      	// 编译器默认生成MyQueue的析构函数调用了Stack的析构,释放的Stack内部的资源
      	// 显示写析构,也会自动调用Stack的析构
      	~MyQueue()
      	{
      		cout 
      	MyQueue mq;
      	//stack st1;
      	//stack st2;
      	return 0;
      }
      
      public:
      	Date(int year = 1, int month = 1, int day = 1)
      	{
      		_year = year;
      		_month = month;
      		_day = day;
      	}
      	//  error C2652: “Date”: 非法的复制构造函数: 第一个参数不应是“Date”
      	// Date d2(d1)
      	Date(const Date& d)
      	{
      		_year = d._year;
      		_month = d._month;
      		_day = d._day;
      	}
      	void Print()
      	{
      		cout 
      //	return d1._year == d2._year
      //		&& d1._month == d2._month
      //		&& d1._day == d2._day;
      //}
      bool operator==(Date d2)
      {
      	return _year == d2._year
      		&& _month == d2._month
      		&& _day == d2._day;
      }
      int main()
      {
      	Date x1(2024, 7, 10);
      	Date x2(2024, 7, 11);
      	//operator==(x1, x2);
      	//x1 == x2;
      	x1.operator==(x2);
      	x1 == x2;
      	return 0;
      }
      
      	return d1._year == d2._year
      		&& d1._month == d2._month
      		&& d1._day == d2._day;
      }
      int main()
      {
      	// 运算符重载函数可以显示调用
      	operator==(d1, d2);
      	// 编译器会转换成 operator==(d1, d2);
      	d1 == d2;
      	return 0;
      }
      
      	//默认是private 
      	int x;
      	int y;
      public:
      	func(int xp = 0, int yp = 0)
      	{
      		x = xp;
      		y = yp;
      	}
      	//const成员函数内无法修改类的数据成员,否者编译器会报错
      	void print() const
      	{
      		x = 5;//试图修改x 将引发编译器报错 
      		cout 
      	//默认是private 
      	int x;
      	int y;
      public:
      	func(int xp = 0, int yp = 0)
      	{
      		x = xp;
      		y = yp;
      	}
      	void Print2()
      	{
      		cout 
      		//x=5;//试图修改成员变量 将引发编译器报错 
      		Print2(); //试图调用非const成员 引发编译器报错
      		cout 

VPS购买请点击我

文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。

目录[+]