前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >类成员初始化和赋值的内幕

类成员初始化和赋值的内幕

作者头像
混说Linux
发布2022-07-14 19:43:15
3860
发布2022-07-14 19:43:15
举报
文章被收录于专栏:混说Linux混说Linux

定义一个变量,就是在内存中为你定义的这个变量开辟一段内存空间,如果这个变量没有初始化,那么系统会随机给这个变量赋一个值,这个值我一般称它为"垃圾数"。

没有初始化的变量我认为它是没有意义的,是在浪费内存,就比如人刚出生的时候上帝需要给他赋予点东西,比如条件反射,比如哭,比如吮吸........这样人的意义得以体现。

对于类的成员来说,我们最好的做法就是在构造函数中对每一个类成员进行初始化。

我们来看一个简单的例子:

代码语言:javascript
复制
class name
{
public:
    name(int aa, int bb)
    {}
private:
    int a;
    int b;
};

上面例子中的变量 a 和 b 的值都没有在构造函数中初始化,这时候它们的值就会是一个"垃圾数",我们稍微改一下:

代码语言:javascript
复制
class name
{
public:
    name(int aa, int bb):a(aa)
    {
        b = bb;
    }
private:
    int a;
    int b;
};

可以看到 a 的值是用初始化列表的方式进行初始化,而 b 的值是通过构造函数的参数进行赋值。

在类对象调用构造函数的时候,以上两种方式都可以确保 a 和 b 的值是可以确定的,但是初始化和赋值两种方式是有区别的

  1. 初始化发生的时机肯定比赋值早。初始化会在程序刚开始运行的时候发生,而赋值是只有在程序执行到这条语句才会发生。
  2. 初始化的执行效率要比赋值高。类成员在构造函数中执行的赋值语句之前已经被系统进行了初始化,当执行赋值的时候就需要抹掉之前default的初始化的数据,这样就相当于多做了一次无用功,而构造函数中运行的初始化列表则不需要做这次无用功。
  3. 常量成员和引用成员只能使用初始化列表。这是c++的语法。
代码语言:javascript
复制
class name
{
public:
    name(int aa, int bb):b(bb),a(aa)
    {}
private:
    int const a;
    int &b;
};

代码中的类成员 a 和 b 是必须使用初始化列表初始化的,这是c++语法规定的。

另外,类成员的初始化的顺序的固定的:如果有基类的话,先初始化基类,然后按照类中声明的顺序去初始化派生类中的类成员。上述代码中可以看到,构造函数初始化列表是先写 b 后写 a,即使是这样也是会按声明的顺序先初始化 a 后初始化 b。

我们来做一个实验就可以彻底明白:

代码语言:javascript
复制
class Name
{
public:
    Name():b(2),a(b + 2)
    {}
    
    void print()
    {
        cout << "a = " << a << " ,  b = " << b << endl;
    }
private:
    int const a;
    int b;
};

int main()
{
    Name Leon;
    Leon.print();
 
    return 0;
}

编译后的结果为:

结果很明显,当初始化 a 的时候,b还没被初始化为2,b还是个垃圾数,所以最终打印的 a 的值依然是个垃圾数,b 则后面被初始化为 2。

分享是一种积极的生活态度

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-09-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 混说Linux 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档