【C++】类的默认成员函数(上)

小明 2025-04-30 05:20:15 4

🔥博客主页: 小���失眠啦.

🎥系列专栏:《C语言》 《数据结构》 《C++》 《Linux》 《Cpolar》

❤️感谢大家点赞👍收藏⭐评论✍️


文章目录

  • 一、默认成员函数
  • 二、构造函数
    • 构造函数的概念及特性
    • 三、析构函数
      • 析构函数的特性
      • 四、拷贝构造函数
        • 拷贝构造函数的特性

          一、默认成员函数

          上一章中我们谈到,如果一个类中什么成员也没有,那么这个类就叫作空类。其实这么说是不太严谨的,因为一个类不可能什么都没有。

          当我们定义好一个类,不做任何处理时,编译器会自动生成以下6个默认成员函数:

          • 默认成员函数:如果用户没有手动实现,则编译器会自动生成的成员函数。

            • 构造函数:主要完成初始化工作;
            • 析构函数:主要完成清理工作;
            • 拷贝构造:使用一个同类的对象初始化创建一个对象;
            • 赋值重载:把一个对象赋值给另一个对象;
            • 取地址重载:普通对象取地址操作;
            • 取地址重载(const):const对象取地址操作;

              本章我们将学习四个默认成员函数——构造函数与析构函数——拷贝构造 与赋值重载


              二、构造函数

              在C语言阶段,我们实现栈的数据结构时,有一件事很苦恼,就是每当创建一个stack对象(之前叫作定义一个stack类型的变量)后,首先得调用它的专属初始化函数StackInit来初始化对象。

              typedef int dataOfStackType;
              typedef struct stack
              {
              	dataOfStackType* a;
              	int top;
              	int capacity;
              }stack;
              void StackInit(stack* ps);
              //...
               int main()
               {
              	 stack s;
              	 StackInit(&s);
              	 //...
              	 return 0;
               }
              

              这不免让人觉得有点麻烦。在C++中,构造函数为我们很好的解决了这一问题。

              构造函数的概念及特性

              构造函数是一个特殊的成员函数。构造函数虽然叫作构造,但是其主要作用并不是开辟空间创建对象,而是初始化对象。

              构造函数之所以特殊,是因为相比于其它成员函数,它具有如下特性:

              1. 函数名与类名相同;
              2. 无返回值;
              3. 对象实例化时,编译器自动调用对应的构造函数;
              4. 构造函数可以重载;

              举例

              class Date
              {
              public:
              	//无参的构造函数
              	Date()
              	{};
              	//带参的构造函数
              	Date(int year,int month,int day)
              	{
              		_year = year;
              		_month = month;
              		_day = day;
              	}
              private:
              	int _year;
              	int _month;
              	int _day;
              };
              void TestDate()
              {
              	Date d1;//调用无参构造函数(自动调用)
              	Date d2(2023, 3, 29);//调用带参构造函数(自动调用)
              }
              

              特别注意

              • 创建对象时编译器会自动调用构造函数,若是调用无参构造函数,则无需在对象后面使用()。否则会产生歧义:编译器无法确定你是在声明函数还是在创建对象。

                错误示例

                //错位示例
                Date d3();
                
                1. 如果类中没有显式定义构造函数,则C++编译器会自动生成一个无参的默认构造函数,一旦用户显式定义编译器将不再生成。
                class Date
                {
                public:
                	//若用户没有显示定义,则编译器自动生成。
                	/*Date(int year,int month,int day)
                	{
                		_year = year;
                		_month = month;
                		_day = day;
                	}*/
                private:
                	int _year;
                	int _month;
                	int _day;
                };
                
                1. 默认生成构造函数,对内置类型成员不作处理;对自定义类型成员,会调用它的默认构造函数;
                • C++把类型分成内置类型(基本类型)和自定义类型。内置类型就是语言提供的数据类型,如:int、char、double…,自定义类型就是我们使用class、struct、union等自己定义的类型。

                  举例

                  默认构造函数对内置类型

                  class Date
                  {
                  public:
                  	//此处不对构造函数做显示定义,测试默认构造函数
                  	/*Date()
                  	{}*/
                  	void print()
                  	{
                  		cout 
                  	Date d1;
                  	d1.print();
                  }
                  
                  public:
                  	//此处对stack构造函数做显示定义
                  	stack()
                  	{
                  		cout 
                  public:
                  	//此处不对queue构造函数做显示定义,测试默认构造函数
                  	/*queue()
                  	{}*/
                  private:
                  	//自定义类型成员
                  	stack _s;
                  };
                  void TestQueue()
                  {
                  	queue q;
                  }
                  
                  public:
                  //...
                  	void print()
                  	{
                  		cout 
                  	Date d2;
                  	d2.print();
                  }
                  
                  public:
                  	//无参的默认构造函数
                  	//Date()
                  	//{
                  	//}
                  	//全缺省的默认构造函数
                  	Date(int year = 0, int month = 0, int day = 0)
                  	{
                  		_year = year;
                  		_month = month;
                  		_day = day;
                  	}
                  	void print()
                  	{
                  		cout 
                  public:
                  	Stack()
                  	{
                  		//...
                  	}
                  	void Push(int x)
                  	{
                  		//...
                  	}
                  	bool Empty()
                  	{
                  		// ...
                  	}
                  	int Top()
                  	{
                  		//...
                  	}
                  	void Destory()
                  	{
                  		//...
                  	}
                  private:
                  	// 成员变量
                  	int* _a;
                  	int _top;
                  	int _capacity;
                  };
                  void TestStack()
                  {
                  	Stack s;
                  	st.Push(1);
                  	st.Push(2);
                  	//过去需要手动释放
                  	st.Destroy();
                  }
                  
                  public:
                  	Date()
                  	{
                  		cout 
                  		cout 
                  	Date d3;
                  	//d3生命周期结束时自动调用构造函数
                  }
                  
                  public:
                  	//此处对stack构造函数做显示定义
                  	stack()
                  	{
                  		cout 
                  		cout 
                  public:
                  	//此处不对queue构造函数做显示定义,测试默认构造函数
                  	/*queue()
                  	{}*/
                  private:
                  	//自定义类型成员
                  	stack _s;
                  };
                  void TestQueue1()
                  {
                  	queue q;
                  }
                  
                  public:
                  	//构造函数
                  	Date()
                  	{
                  		cout 
                  		cout 
                  		cout 
                  	Date d1;
                  	//调用拷贝构造创建对象
                  	Date d2(d1);
                  }
                  
                  public:
                  	//错误示例
                  	//如果这样写,编译器就会直接报错,但我们现在假设如果编译器不会检查,
                  	//这样的程序执行起来会发生什么
                  	Date(const Date d)
                  	{
                  		_year = d._year;
                  		_month = d._month;
                  		_day = d._day;
                  	}
                  private:
                  	int _year = 0;
                  	int _month = 0;
                  	int _day = 0;
                  };
                  void TestDate()
                  {
                  	Date d1;
                  	//调用拷贝构造创建对象
                  	Date d2(d1);
                  }
                  
                  public:
                  	//构造函数
                  	Date(int year = 0, int month = 0, int day = 0)
                  	{
                  		//cout 
                  		cout 
                  	Date d1(2023, 3, 31);
                  	//调用拷贝构造创建对象
                  	Date d2(d1);
                  	d2.print();
                  }
                  
                  public:
                  	stack(int defaultCapacity=10)
                  	{
                  		_a = (int*)malloc(sizeof(int)*defaultCapacity);
                  		if (_a == nullptr)
                  		{
                  			perror("malloc fail");
                  			exit(-1);
                  		}
                  		_top =  0;
                  		_capacity = defaultCapacity;
                  	}
                  	~stack()
                  	{
                  		cout 
                  		_a[_top++] = n;
                  	}
                  	void print()
                  	{
                  		for (int i = 0; i 
The End
微信