C++ 05 _构造函数

C++中的构造函数是一个特殊成员函数,用于在对象创建时初始化数据成员。当类中没有任何内容时,也会默认生成6个成员函数。构造函数在对象实例化时由编译器自动调用,确保每个数据成员都有初始值,并且在整个对象生命周期中只调用一次。构造函数可以重载,但默认构造函数只能有一个。它们的主要任务是初始化,而非创建对象空间。在自定义类型中,构造函数会调用对应的构造函数进行初始化,提高效率。
摘要由CSDN通过智能技术生成
class Date{} //这是一个空类

如上图, 我们已经知道空类在计算大小的时候会占一个字节.

那么空类中确实什么都没有么? 其实, 任何一个类在没有内容的情况下, 都会自动生成6个默认成员函数.  它们分别是

下面, 让我们开始学习构造函数

class Date
{
    public:
    void SetDate(int year, int month, int day)
    {
        _year = year;
        _month = month;
        _day = day;
    }

    void Display()
    {
        cout << _year << " -" << _month << " -" << _day << endl;
    }

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

int main()
{
    Date d1,d2;
    d1.SetDate(2018,5,1);
    d1.Display();
    
    d2.SetDate(2018,7,1);
    d2.Display();
    return 0;
}

对于Date类, 可以通过SetDate公有的方式给对象设置内容, 但是如果每次创建对象都调用该方法设置信息, 未免有点麻烦.那能否在对象创建时. 就将信息设置进去呢?

构造函数是一个特殊的成员函数, 名字与类名相同, 创建类 类型对象时由编译器自动调用, 保证每个数据成员都有一个合适的初始值, 并且在对象的生命周期内只调用一次.

下面通过代码具体认知一下构造函数

构造函数是特殊的成员函数, 需要注意的是, 构造函数的虽然名称叫构造, 但是需要注意的是构造函数的主要任务并不是开空间创建对象, 而是初始化对象.

class Date
{

public:
    //1, 无参构造函数
    Date()
    {}

    //2, 带参构造函数
    Date(int year, int month, int day)
    {
        _year = year;
        _month = month;
        _day = day;
    }
    //此处构成函数重载, 函数的形参不同
    
   /* Date(int year = 1900, int month = 1, int day = 1)
		{
			_year = year;
			_month = month;
			_day = day;
		}
   // 如果替换成该注释部分, 此处将不构成函数重载, 编译错误, 因为全缺省的构造函数和无参的构造函数都属于默认构造函数, 默认构造函数只能有一个.*/  
private:
    int _year;
    int _month;
    int _day;
};

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

    //注意: 如果通过无参构造函数创建对象时, 对象后面不用加括号, 不然就成了函数声明
    //比如这个例子
    Date d3();
    //这句代码声明了d3函数,该函数无参, 返回一个日期类型的对象.
}

至此, 让我们来总结一波构造函数的特征

特征如下:

1.函数名与类名相同. 

2.无返回值

3.对象实例化时编译器自动调用对应的构造函数.

4.构造函数可以重载.

5. 构造函数重载是有限制的, 如果一个类中有同名的全缺省的构造函数和无参的构造函数,将不构成重载, 因为都属于默认构造函数, 而默认构造函数只能有一个.

那么构造函数有没有缺点呢?  我们再来对比一下构造函数Date(int,int,int)从使用和结构上来看和SetDate是比较接近的, 而无参的构造函数Date d1 在调用后,对象year/month/day依然是随机值, 那么这个构造函数的好处究竟在哪儿呢?  

让我们先接着往下看


class Time
{
public:    
    //这是一个无参构造函数   
    Time()
    {
        cout<< "Time()" <<endl;
        _hour = 0;
        _minute = 0;
        _second = 0;
    }
private:
    int _hour;
    int _minute;
    int _second;
};


这是一个时间类, 调用其构造函数时会将成员变量初始化.  比如说Time t1; 这条语句会对Time进行实例化, 返回一个Time 类的时候已经对成员变量进行了初始化. 这不就提高了效率么.

如果是在类里面又有一个类(即自定义的成员), 针对于这种情况, 构造函数会如何处理呢?


class Date
{
private:
    //基本类型(内置类型)
    int _year;
    int _month;
    int _day;

    //自定义类型
    Time _t;   //这里是在Date类中定义了一个Time 类
};

int main()
{
    Date d1;
    return 0;
}

这段代码请大家自行调试验证, 可以发现int类型的年月日并没有被初始化, 而Time类中的时,分,秒被正确初始化为0了

解答: C++把类型分为内置类型(基本类型)和自定义类型. 内置类型就是语法已经定义好的类型: 如Int / char 等等  , 自定义类型就是我们使用class / struct / union自定义的类型 . 当我们进行调试时, 可以知道Date类默认生成的构造函数对内置类型并没有处理, 但是对于自定义类型Time类来讲, 调用了Time构造函数, 从而初始化了时,分,秒三个变量.

下面我们接着看一下成员变量的命名风格

//不好的成员变量命名
class Date
{
public:
    Date(int year)
    {
        //这里的year到底是成员变量, 还是函数形参呢
        year = year;
    }

private:
    int year;
};

//推荐的成员变量命名
class Date
{
public:
    Date(int year)
    {
        _year = year;
    }
private:
    int year;
};

//另一种推荐的成员变量命名

class Date
{
public:
 Date(int year)
 {
 m_year = year;
 }
private:
 int m_year;
};

下一篇_析构函数

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值