C++ 构造函数与this指针

         之前一直理解的构造函数的参数里没有this指针,因为此时对象还没生成,其他非static成员函数才有this指针,因为当它们被调用时对象已经生成了。然而这样理解是错误的,构造函数参数里也是有this指针的,但这个this指针只是指向了一个内存地址,这个内存地址还并不代表一个类对象,当构造函数完成后,这个地址有足够的信息后才表示这是一个类对象。

#include <stdio.h>
#include <stdlib.h>
#include <string>

struct Test
{
    char a;
    int b;
    int c;
    std::string str;
};

class CBase
{
public:
    CBase(): mValue(100)
    {
        printf("constructor, mValue = %d\n", mValue); 
    }
    ~CBase()
    {
        printf("destructor\n"); 
    }

    int getValue()const
    {
        return mValue;
    }
private:
    int mValue;
    Test mData;
};


int main()
{
    printf("sizeof(CBase) = %lu\n", sizeof(CBase));

    CBase *instance = new CBase();


    int value = instance->getValue();
    delete instance;

    return 0;
}

在 new 那行添加断点,如:

 从这里应该可以看出,在构造函数之前,this指针已经分配了,指向的内存为0x602010,那我们可以看下这个内存里有什么,如:

 此时内存里都是0,这里的x/8xw 表示打印8个单元内容,每个单元4个字节,以16进制显示,因为sizeof(CBase) = 32,所以这里打印了 32 个字节的内容。再单步往下执行,会调用 struct Test结构体的构造函数,及进行到初始化列表,如:

 到这里已经进到构造函数里面了,其成员数据已经初始化完成,我们可以看到此时this指向的内存的内容发生了变化,this指向的前4个字节变成了 0x00000064,其10进制就是:100,就是初始化列表里的 mValue(100),最后两个应该是std::string 变量里的值(std::string 的内存结构这里不详述,有兴趣的同学可以去研究一下)。然后非static成员函数调用时,此时this指针指向的内容就是构造函数构造出来的内容,如:

所以,我们可以得出,构造函数里的this指针指向的就是一块空内存(内容可能也是随机的),而非static成员函数里的this指针,其内存里已经有了初始化值(通过初始化列表或构造函数里赋值)。我们这里是用到了 new 操作符,那我们可以看一下 new 操作符是怎样工作的,这样也可以验证我们的结论。这里找到的文档为 microsoft 的文档:new 操作符如何工作,截取一段内容:

How new works

The new-expression (the expression containing the new operator) does three things:

  • Locates and reserves storage for the object or objects to be allocated. When this stage is complete, the correct amount of storage is allocated, but it's not yet an object.

  • Initializes the object(s). Once initialization is complete, enough information is present for the allocated storage to be an object.

  • Returns a pointer to the object(s) of a pointer type derived from new-type-id or type-id. The program uses this pointer to access the newly allocated object.

The new operator invokes the function operator new. For arrays of any type, and for objects that aren't classstruct, or union types, a global function, ::operator new, is called to allocate storage. Class-type objects can define their own operator new static member function on a per-class basis.

When the compiler encounters the new operator to allocate an object of type T, it issues a call to T::operator new( sizeof(T) ) or, if no user-defined operator new is defined, ::operator new( sizeof(T) ). It's how the new operator can allocate the correct amount of memory for the object.

文档里说明,第一步完成时,此时所分配的内存并未表示是一个 “对象”,当第2步完成后,此时的内存才表示是一个“对象”。

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值