C++值函数的初始化与拷贝

本文探讨了C++中将对象作为值类型时遇到的问题,特别是关于SomeType对象的指针在构造过程中出现的意外行为。揭示了由于栈上临时变量的拷贝导致的指针失效现象,并提供了两种解决方案。

非常坑!当把对象作为值类型的时候,比如SomeType是SomeSucker的一个值类型

class SomeSucker {
    SomeType something;
    SomeSucker() {
        something = SomeType();
        some_method();
    } 
};

class SomeType() {
    int arr[100];
    int* ptr;
    SomeType() {
        ptr = &arr[0];
    }
    void some_method() {
       ...
       assert(ptr == &arr[0]);
    }
};

当我们运行some_method时,会惊奇地发现,ptr != &arr[0] !即使我们已经写了 ptr = &arr[0]; 这是为什么呢?
原来,something = SomeType();在初始化时(等式右边计算时),SomeType()是一个栈上的临时变量,之后它才被拷贝到something这个成员变量中,因此第一次运行 ptr = &arr[0]; 和之后计算 &arr[0];,用的arr[0] 不是一个位置上的 arr[0],它已经因为拷贝移动了,但是ptr 没有更新。

要解决这个问题,无非两个办法:

  1. 直接在声明时构造,记住使用直接构造而不是拷贝构造,cannot risk that

    class SomeSucker {
        SomeType something;
        SomeSucker(): something(SomeType()) {
        } 
    };
    

    注意如果不在初始化表中指明something的初始化方式的话,会自动调用其无参构造函数、

  2. 找一个合适的实际初始化 ptr,不要在初始化的时候设定它。

c++ 真是硬核语言!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值