V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
814084764
V2EX  ›  程序员

在堆?还是栈?

  •  
  •   814084764 · Sep 25, 2018 · 5350 views
    This topic created in 2780 days ago, the information mentioned may be changed or developed.

    C++

    class Target{ private: int a; }

    class Object { private : Target target; }

    Object* obj = new Object;

    请问:target 是在堆上?还是栈上??

    30 replies    2018-09-26 16:22:44 +08:00
    poorcai
        1
    poorcai  
       Sep 25, 2018 via iPhone
    堆上
    poorcai
        2
    poorcai  
       Sep 25, 2018 via iPhone
    @poorcai #1 说错,在栈上
    innoink
        3
    innoink  
       Sep 25, 2018
    private : Target target;
    这只是一个结构描述,并不是实际会执行的语句。
    所以,肯定是都在堆上啊
    tinykey
        4
    tinykey  
       Sep 25, 2018
    堆上啊大兄 dei
    000wangxinyu000
        5
    000wangxinyu000  
       Sep 25, 2018
    @poorcai 为啥在栈上啊
    current
        6
    current  
       Sep 25, 2018
    @poorcai 为啥是栈? CPP 同一个 instance 还能拆成几块,一部分在堆上一部分在栈上不成
    innoink
        7
    innoink  
       Sep 25, 2018
    同样是 int a; 在一个函数里这句话会被执行,作用是开一个局部变量
    在一个结构描述里,这句话不会被执行,只是起到描述作用,有这么一个类型的成员,具体成员放在哪不管
    814084764
        8
    814084764  
    OP
       Sep 25, 2018
    @innoink 不是在创建的时候自动调用成员变量的构造方法么?

    @tinykey 这个 target 不是程序员需要手动释放的,不是在栈上么?
    814084764
        9
    814084764  
    OP
       Sep 25, 2018
    @innoink 也就是说,在创建 Object 的时候,不会自动调用成员变量 target 的构造方法了?

    @current 不可以吗?不知道。。哈哈
    innoink
        10
    innoink  
       Sep 25, 2018
    @innoink 构造方法里面也不是 int a;啊
    都是类似这种:
    this->a = parameter_a;这样的
    iceheart
        11
    iceheart  
       Sep 25, 2018 via Android
    只能说是 new 出来的,想把它摆在栈上也不难
    innoink
        12
    innoink  
       Sep 25, 2018
    @814084764 构造方法中,没有办法知道自己是在栈上还是在堆上。构造方法只是用来初始化成员的,并不能用来产生成员。
    814084764
        13
    814084764  
    OP
       Sep 25, 2018
    @innoink 可能我的例子写的不全。
    比如 Target 有一个函数:int getA(){return a };

    Object 中调用 target.getA()。这个时候已经产生成员了吧?
    这个时候 target 是在堆还是栈呢?
    bytelee
        14
    bytelee  
       Sep 25, 2018
    target 在哪 取决于你是怎么生成的他吧
    innoink
        15
    innoink  
       Sep 25, 2018
    @814084764 Object 中调用 target.getA()
    你要在哪里调用这个? Obejct 的构造函数吗?还是一样的。在 obj 创建之时,在 Object()调用之时,target 就已经有内存了,只不过没有初始化。Object()的作用只是初始化 target,并不能决定 target 在哪里分配。
    MeteorCat
        16
    MeteorCat  
       Sep 25, 2018 via Android
    按你生成的方式决定
    innoink
        17
    innoink  
       Sep 25, 2018
    @814084764 你的意思可能是:
    class Object
    {
    public:
    int foo()
    {
    return target.getA();
    }
    private:
    Target target;
    }

    首先,这里还是不知道 target 是在堆上还是栈上,但是没关系,就算 target 没分配内存,getA()的函数代码都在那里,都能调用。你要是问"target 都没有怎么返回 a"?成员函数隐含传入 this 指针,只要运行时 this 指针能确定就行了;在 foo 里面,也会有 Object 的 this 指针,通过偏移量能计算出 target 的 this 指针传给 getA()。
    linghutf
        18
    linghutf  
       Sep 25, 2018
    堆上,Target target 只是声明了一个对象,还没有实例化,在 new Object 后调用其默认构造函数,于是 target 初始化到堆上。
    broker
        19
    broker  
       Sep 25, 2018
    可以把 target 改成一个大数组,直到报错,看看报什么错。。。
    tangweihua163
        20
    tangweihua163  
       Sep 25, 2018
    一个实例部分在栈上部分在堆上还真是常有的事。
    bumz
        21
    bumz  
       Sep 25, 2018
    Object 在堆的时候在堆,Object 在栈的时候在栈

    习惯了 java 是不是很难受 hhh
    zwh2698
        22
    zwh2698  
       Sep 25, 2018 via Android
    Target 改什么都在堆上,内存的分配主要是开对象分配的方式,如果 new 和 placement new 一般在堆,但是后者可以放在栈上,那也是提前你保留了。栈都是编译时候就决定了,大小在这个时候一定可以推导出来,堆是在运行时候分配,大小要看上下文
    senxxx
        23
    senxxx  
       Sep 25, 2018 via Android
    @poorcai 大兄弟。在栈上的话。。如果 obj 指针被作为返回值返回给上一层。。那此时的 target 是个什么情况?
    yujincheng08
        24
    yujincheng08  
       Sep 25, 2018 via Android
    linshuang
        25
    linshuang  
       Sep 26, 2018
    肯对是堆,要是栈,你觉得它能用么。。。
    seancheer
        26
    seancheer  
       Sep 26, 2018
    堆啊。。

    target 占用的内存是属于 new 出来的 obj 的,obj 是你 new 出来的,那么就在堆上。

    如果直接 Object obj,那么就是在栈上面。

    class Object 的时候,这个属于声明,不会占用内存的。
    justou
        27
    justou  
       Sep 26, 2018
    堆上. 不能在栈上的原因上面提到了. C++也可以 new 在栈上, 叫 placement new, 在某些场景下非常有用

    https://www.geeksforgeeks.org/placement-new-operator-cpp/
    wizardoz
        28
    wizardoz  
       Sep 26, 2018
    凡是 new 的都在堆上
    cuzfinal
        29
    cuzfinal  
       Sep 26, 2018
    当然是在堆上了,难道 object 里 int a = 1 会在栈上吗?
    dychenyi
        30
    dychenyi  
       Sep 26, 2018
    堆上啊。
    反证法:Target target 如果在栈生成,每个类都是由子类和数据类型构成的,那么没有一个类能在堆上了。
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   1005 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 71ms · UTC 18:58 · PVG 02:58 · LAX 11:58 · JFK 14:58
    ♥ Do have faith in what you're doing.