• 关于构造函数和this调用的思考


    文中一系列思考和内容引发自以下问题:
    我需要在一个类的构造函数中调用另一个对象的构造函数,并使用this初始化其中的一个引用成员。

    主要遇到的问题:

    1. 构造函数的初始化列表中能访问this吗?

    很明显c++创建一个对象分为两部分,创建内存和调用构造函数。
    显然在初始化列表中,当前对象占用的内存已经创建好了,ok,this是可以访问的,只是其中的某些成员是没有初始化的(因为没有构造函数还没执行完,只能说对象是部分有效的)。

    那也间接说明一个问题,在构造函数的函数体中使用this是完全可靠的,所有编译器可以自动初始化的成员都完成了初始化(比如基类的成员、带有默认构造函数的成员,注意具体初始化顺序是由类成员定义顺序确定的),但当前类的部分未在初始化列表中初始化的且没有默认构造函数类成员变量(比如常见的c++内置类型,int、float、指针等)的值是未定义的。

    2. 构造函数参数与成员同名

    构造函数的形式如下:带有一个和类成员同名的参数。打印输出只是为了验证成员变量是否初始化。

    class A
    {
    public:
        A(int a): a(a){cout<<a<<endl;}
    private:
        int a;
    };

    由于初始化列表中不能直接出现this,所以编译器会处理这种重名的情况。也就说,你不能在构造函数的初始化列表中显式用this做限定符,比如下面代码是无法通过编译的:

    A:this->a(a){}

    3. 如何在一个类的构造函数汇中调用另一个构造函数

    构造函数是不允许嵌套调用的,但可以调用不同的重载形式。比如下面代码:(注意这是一道面试题目)

    struct CLS
    {
        int m_i;
        CLS( int i ) : m_i(i){}
        CLS(){CLS(0);}
    };
    int main()
    {
        CLS obj;
        cout << obj.m_i << endl;
        return 0;
    }

    输出是多少?

    ---------------------------------------------------------------------------

    答案是未知,因为m_i是未初始化的变量,是个野值。

    "CLS(0);"的语句表示创建一个临时的CLS对象,并把该对象的成员m_i初始化为0。当前对象的值并没有初始化。

    如果需要实现构造函数类调用另一个构造函数,需要借助于placement new运算符。代码如下:

    struct CLS
    {
        int m_i;
        CLS( int i ) : m_i(i){}
        CLS()
        {
            new (this)CLS(0);
        }
    };    

    如果你对placement new不了解,建议看看c++ primer或者TCPL。

    在c++11中可以直接通过委托或继承构造函数的形式实现上面功能。

    struct CLS
    {
        int m_i;
        CLS( int i ) : m_i(i){}
        CLS():CLS(0){}
    };

    4. 解决方案

    写到这里。我对于构造函数的初始化列表中引用this的情况基本了解,可以用下面代码解决本文开始提出的问题。

    class Context;
    class Ref
    {
    public:
        Ref(Context&context):context(context){}
    private:
        Context &context;
    };
    class Context
    {
    public:
        Context():ref(*this){}
    private:
        Ref ref;
    };

    复述下开始的问题:我需要在一个类的构造函数中调用另一个对象的构造函数,并使用this初始化其中的一个引用成员。

    类Context会在其构造函数的初始化列表中通过this调用Ref的构造函数。

    5. 参考资料

    [1] 从一道题谈C++中构造函数调用构造函数    http://www.cnblogs.com/chio/archive/2007/10/20/931043.html

    [2] c++ 一个构造函数 调用 另一个 构造函数    http://www.cnblogs.com/ayanmw/archive/2012/08/20/2647808.html

  • 相关阅读:
    红帽RHEL7版本RHCE认证学习及考试经历
    高手总结的“恋爱法”学习Linux系统,效果更好。
    IT技术学习指导之Linux系统入门的4个阶段(纯干货带图)
    深度剖析Linux与Windows系统的区别
    浅谈学习掌握linux系统的优势
    新手要想学好Linux系统就必须做好这四件事情
    为什么高手离不了Linux系统?这就是我的理由
    总结七条助你成为Linux高手的超棒忠告
    分享记录我的Linux系统入门学习经验
    Oracle--表有LONG类型复制或导数报ORA00990
  • 原文地址:https://www.cnblogs.com/tocy/p/ctor-with-this-in-initializer.html
Copyright © 2020-2023  润新知