当前位置:   article > 正文

[C++] 类和对象 _ 剖析构造、析构与拷贝

[C++] 类和对象 _ 剖析构造、析构与拷贝


一、构造函数

构造函数是特殊的成员函数,它在创建对象时自动调用。其主要作用是初始化对象的成员变量(不是开辟空间)。构造函数的名字必须与类名相同,且没有返回类型(即使是void也不行)。

在C++中,构造函数是专门用于初始化对象的方法。当创建类的新实例时,构造函数会自动被调用。通过构造函数,我们可以确保对象在创建时就被赋予合适的初始状态。下面我将详细解释如何使用构造函数进行初始化操作,并以Date类为例进行说明。

创建一个Date类:

class Date 
{  
public:  
    // 成员函数...  
private:  
    int _year;  
    int _month;  
    int _day;  
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

构造函数的特征

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

无参构造

无参构造函数允许我们创建Date对象而不提供任何参数。但是,需要注意的是,如果我们不在无参构造函数中初始化成员变量,那么这些变量的初始值将是未定义的,这可能会导致程序出错。
Date d1; // 调用无参构造函数

class Date 
{  
public:  
    // 1. 无参构造函数  
    Date() 
    {  
        // 在这里可以添加一些初始化代码,例如设置默认日期  
        // 例如:_year = 2000; _month = 1; _day = 1;  
    }  
  
    // 其他成员函数...  
  
private:  
    int _year;  
    int _month;  
    int _day;  
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

带参构造

带参构造可以和无参构造函数重载,因为在之后调用的时候不会受影响,可以与之后讲解的全缺省构造函数和无参构造函数之间的不能函数重载的进行区别。

带参构造函数可以在对对象进行初始化的时候进行传参,传参的数值会直接进行初始化对象中的成员变量。
Date date2(2023, 3, 15); // 调用带参构造函数创建对象,并初始化日期为2023年3月15日

class Date 
{  
public:  
    // 1. 无参构造函数  
    Date() 
    {  
        // ...  
    }  
  
    // 2. 带参构造函数  
    Date(int year, int month, int day) 
    {  
        _year = year;  
        _month = month;  
        _day = day;  
    }  
  
    // 其他成员函数...  
  
private:  
    int _year;  
    int _month;  
    int _day;  
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

在这个带参构造函数中,我们通过参数year、month和day来初始化_year、_month和_day成员变量。这样,我们就可以在创建Date对象时直接指定日期了。

注意区别创造对象的格式

Date d1; // 调用无参构造函数
Date d2(2015, 1, 1); // 调用带参的构造函数
  • 1
  • 2

默认无参构造函数

参考代码:

class Date
{
public:
/*
// 如果用户显式定义了构造函数,编译器将不再生成
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类中构造函数屏蔽后,代码可以通过编译,因为编译器生成了一个无参的默认构造函// 将Date类中构造函数放开,代码编译失败,因为一旦显式定义任何构造函数,编译器将不再
    生成
    // 无参构造函数,放开后报错:error C2512: “Date”: 没有合适的默认构造函数可用
    Date d1;
    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
  • 30
  • 31

在C++中,如果你没有为类显式定义任何构造函数,编译器会为你自动生成一个默认的无参构造函数。这个默认构造函数不会执行任何操作,也不会初始化类的成员变量。这意味着,如果你的类Date没有显式定义任何构造函数,那么你可以创建一个Date对象而不提供任何参数,编译器会为你调用这个默认构造函数。
然而,一旦你为类显式定义了任何构造函数(无论是带参还是无参),编译器就不会再自动生成默认构造函数了。因此,如果你屏蔽了Date类中的带参构造函数,编译器会为你生成一个默认构造函数,所以你可以直接这样创建对象:

Date d1;
  • 1

但是,当你放开带参构造函数时,由于你已经显式定义了至少一个构造函数,编译器就不会再为你生成默认构造函数了。因此,在尝试这样创建对象时,编译器会报错,因为它找不到一个合适的默认构造函数来调用。错误信息表明编译器找不到一个可以调用的构造函数,因为没有默认构造函数可用。

不显式定义构造函数(系统默认生成)

请注意:
默认构造函数只对自定义类型进行初始化,内置类型不做处理。
但是自定义类型的最终还是要对自定义类型中的内置类型进行初始化,所以要在类创建的时候就做好处理。

问题的解决方式

问题描述:
显式定义构造函数的影响:一旦你为类显式定义了至少一个构造函数(无论带参还是不带参),编译器就不会再自动生成默认构造函数。这意味着如果你想要创建类的对象而不提供任何参数,你必须自己定义一个无参构造函数,否则编译器会报错,因为它找不到一个合适的构造函数来调用。

显式定义的无参构造函数
class Date 
{
public:
	// 显式定义的无参构造函数  
	Date() 
	{
		_year = 0;
		_month = 0;
		_day = 0;
	}

	// 其他成员函数...  

private:
	int _year;
	int _month;
	int _day;
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

带参构造函数
// 带参构造函数  
    Date(int year, int month, int day) 
    {  
        _year = year;  
        _month = month;  
        _day = day;  
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

全缺省参数的构造函数

C++11

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/522104
推荐阅读
相关标签