前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C++ 类成员变量初始化

C++ 类成员变量初始化

作者头像
mzlogin
发布2020-04-14 20:38:50
2.3K0
发布2020-04-14 20:38:50
举报
文章被收录于专栏:闷骚的程序员

本文是对《Effective C++》的”Item 4: Make sure that objects are initialized before they’re used”的笔记和验证。

结论

  1. 在进入构造函数体之前,数据成员的初始化就已完成。
  2. 数据成员的初始化顺序取决于声明顺序。

结论 1 证明

证明代码片段:

代码语言:javascript
复制
#include <stdio.h>

class CA
{
public:
    CA(const char* pName = "default")
    {
        printf("CA::CA(const char*) pName = %s\n", pName);
    }

    CA(const CA& a)
    {
        printf("CA::CA(const CA&)\n");
    }

    CA& operator = (const CA& a)
    {
        printf("CA::operator =\n");
        return *this;
    }
};

class CTest
{
public:
    CTest(CA& a)
    {
        printf("CTest::CTest(CA)\n");
        m_a = a;
    }

private:
    CA m_a;
};

int main()
{
    CA a("special");
    CTest test(a);
    return 0;
}

输出:

代码语言:javascript
复制
CA::CA(const char*) pName = special
CA::CA(const char*) pName = default
CTest::CTest(CA)
CA::operator =

这已经能很好地证明结论 1。而进入函数体之前的数据成员的初始化如何控制呢?答案就是——成员初始化列表。

让我们来看看将CTest的构造函数改成使用成员初始化列表以后的情况:

代码语言:javascript
复制
    CTest(CA& a): m_a(a)
    {
        printf("CTest::CTest(CA)\n");
    }

输出:

代码语言:javascript
复制
CA::CA(const char*) pName = special
CA::CA(const CA&)
CTest::CTest(CA)

在成员初始化列表的指定下调用了CA的复制构造函数。这两种方式的差别相当于CA a; a = b;CA a(b);的差别,很显然使用成员初始化列表效率要更高一点。

PS: 顺便吐槽一下很多建议使用成员初始化列表而不讲为什么的老师和书,你们多讲一句能费多大劲 T.T。

结论 2 证明

证明代码片段:

代码语言:javascript
复制
#include <stdio.h>

class CA
{
public:
    CA(const char* pName = "default")
    {
        printf("CA::CA(const char*) pName = %s\n", pName);
    }

    CA(const CA& a)
    {
        printf("CA::CA(const CA&)\n");
    }

    CA& operator = (const CA& a)
    {
        printf("CA::operator =\n");
        return *this;
    }
};

class CB
{
public:
    CB(const char* pName = "default")
    {
        printf("CB::CB(const char*) pName = %s\n", pName);
    }

    CB(const CB& b)
    {
        printf("CB::CB(const CB&)\n");
    }

    CB& operator = (const CB& b)
    {
        printf("CB::operator =\n");
        return *this;
    }
};

class CTest
{
public:
    CTest(CA& a, CB& b): m_b(b), m_a(a)
    {
        printf("CTest::CTest(CA)\n");
    }

private:
    CA m_a;
    CB m_b;
};

int main()
{
    CA a("special A");
    CB b("special B");
    CTest test(a, b);
    return 0;
}

输出:

代码语言:javascript
复制
CA::CA(const char*) pName = special A
CB::CB(const char*) pName = special B
CA::CA(const CA&)
CB::CB(const CB&)
CTest::CTest(CA)

可以看出在成员初始化列表中的顺序并无作用,对成员的初始化还是以声明顺序为依据。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2014/07/13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

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

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

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