初识构造函数

举报
芒果_Mango 发表于 2022/07/31 23:12:10 2022/07/31
【摘要】 大家好,我是芒果,一名非科班的在校大学生。对C/C++、数据结构、Linux及MySql、算法等领域感兴趣,喜欢将所学知识写成博客记录下来。 希望该文章对你有所帮助!如果有错误请大佬们指正!共同学习交流作者简介:CSDN C/C++领域新星创作者https://blog.csdn.net/chuxinchangcun?type=blog掘金LV3用户 https://juejin.cn/us...

大家好,我是芒果,一名非科班的在校大学生。对C/C++、数据结构、Linux及MySql、算法等领域感兴趣,喜欢将所学知识写成博客记录下来。 希望该文章对你有所帮助!如果有错误请大佬们指正!共同学习交流

作者简介:


1.类的6个默认成员函数

如果一个类中什么成员都没有,简称为空类。空类中什么都没有吗?并不是的,任何一个类在我们不写的情 况下,都会自动生成下面6个默认成员函数 ->他们是特殊的成员函数,如果我们不进行实现,编译器自动生成一份

 class Date {};  //空类

image-20220116171145523


2. 构造函数

2.1 概念

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

2.2 特性

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

其特征如下:

  1. 函数名与类名相同。
  2. 无返回值。
  3. 对象实例化时编译器自动调用对应的构造函数。 ->对象定义出来就自动调用,这样保证了一个对象是被初始化过的
  4. 构造函数可以重载。
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 ;
};
void TestDate()
{
    Date d1; // 调用无参构造函数
    Date d2 (2015, 1, 1); // 调用带参的构造函数
    // 注意:如果通过无参构造函数创建对象时,对象后面不用跟括号,否则就成了函数声明
    Date d3();
}

注意:如果通过无参构造函数创建对象时,对象后面不用跟括号,否则就成了函数声明


为了简化:可以使用缺省参数

class Date
{
public:
    //构造函数
    //使用全缺省或者半缺省,这样比较好用
    //全缺省构造
    Date(int year = 0, int month = 1, int day = 1)
    {
        _year = year;
        _month = month;
        _day = day;
    }
    //无参构造
    Date()
    {
        _year = 0;
        _month = 1;
        _day = 1;
    }
private:
    int _year;
    int _month;
    int _day;
};
int main()
{
    Date d1;//编译不通过
    return 0;
}

image-20220116210205413

上述的两个构造函数:语法上二者都可以同时存在,是函数重载。不调用就不会有问题。

但是无参调用的时候就会产生歧义。不知道调用的是全缺省的还是无参的构造函数,存在歧义!


5.如果类中没有显式定义构造函数,则C++编译器会自动生成一个无参的默认构造函数,一旦用户显式定 义编译器将不再生成。

class Date
{
public:
/*
// 如果用户显式定义了构造函数,编译器将不再生成
Date (int year, int month, int day)
{
_year = year;
_month = month;
_day = day;
}
*/
private:
int _year;
int _month;
int _day;
};
void Test()
{
// 没有定义构造函数,对象也可以创建成功,因此此处调用的是编译器生成的默认构造函数
Date d;
}

  1. 无参的构造函数和全缺省的构造函数都称为默认构造函数,并且默认构造函数只能有一个。 ->语法上他们可以同时存在,构成函数重载,但是如果有对象定义去无参调用,就会报错。产生歧义

注意:无参构造函数、全缺省构造函数、我们没写编译器默认生成的构造函数,都可以认为是默认成员函数。

C++里面把类型分为两类:内置类型(基本类型),自定义类型

内置类型:int / char / double / 指针 / 内置类型数组等等

自定义类型: struct / class 定义的类型

我们不写构造函数时:编译器默认生成构造函数,对于内置类型的成员变量不做初始化处理,对于自定义类型成员变量回去调用它的默认构造函数初始化,如果没有默认构造函数就会报错。

image-20220116212741458

对于内置类型会去调用自己的默认构造函数,自己写的默认构造函数也需要是公有的,如果是私有的就不能访问了,会报错。

因为我们写了一个构造函数,编译器就不会自动生成了,而这个构造函数不是无参的,也不是全缺省的,编译器找不到默认构造函数,所以出错!

image-20220116213133878


任何一个类的默认构造函数就是:不用参数就可以调用的

任何一个类的默认构造函数就有三个:1.全缺省的构造函数 2.无参构造函数 3.我们不写时,编译器默认生成的。


  1. 关于编译器生成的默认成员函数,很多童鞋会有疑惑:在我们不实现构造函数的情况下,编译器会生成 默认的构造函数。但是看起来默认构造函数又没什么用?d对象调用了编译器生成的默认构造函数,但 是d对象year/month/_day,依旧是随机值。也就说在这里编译器生成的默认构造函数并没有什么卵 用?? 解答:C++把类型分成内置类型(基本类型)和自定义类型。内置类型就是语法已经定义好的类型:如 int/char…,自定义类型就是我们使用class/struct/union自己定义的类型,看看下面的程序,就会发现 编译器生成默认的构造函数会对自定类型成员_t调用的它的默认成员函数
class Time
{
public:
    Time()
    {
        cout << "Time()" << endl;
        _hour = 0;
        _minute = 0;
        _second = 0;
    }
private:
    int _hour;
    int _minute;
    int _second;
};
class Date
{
private:
    // 基本类型(内置类型)
    int _year;
    int _month;
    int _day;
    // 自定义类型
    Time _t;
};
int main()
{
    Date d;
    return 0;
}

image-20220116213310750


  1. 成员变量的命名风格
// 我们看看这个函数,是不是很僵硬?
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;
};
// 其他方式也可以的,主要看公司要求。一般都是加个前缀或者后缀标识区分就行。

\

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。