• 请不要在回答技术问题时复制粘贴 AI 生成的内容
814084764
V2EX  ›  程序员

在堆?还是栈?

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

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

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

    Object 中调用 target.getA()。这个时候已经产生成员了吧?
    这个时候 target 是在堆还是栈呢?
    bytelee
    bytelee
    Sep 25, 2018
    14
    target 在哪 取决于你是怎么生成的他吧
    innoink
    innoink
    Sep 25, 2018
    15
    @814084764 Object 中调用 target.getA()
    你要在哪里调用这个? Obejct 的构造函数吗?还是一样的。在 obj 创建之时,在 Object()调用之时,target 就已经有内存了,只不过没有初始化。Object()的作用只是初始化 target,并不能决定 target 在哪里分配。
    MeteorCat
    MeteorCat
    Sep 25, 2018 via Android
    16
    按你生成的方式决定
    innoink
    innoink
    Sep 25, 2018
    17
    @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
    linghutf
    Sep 25, 2018
    18
    堆上,Target target 只是声明了一个对象,还没有实例化,在 new Object 后调用其默认构造函数,于是 target 初始化到堆上。
    broker
    broker
    Sep 25, 2018
    19
    可以把 target 改成一个大数组,直到报错,看看报什么错。。。
    tangweihua163
    tangweihua163
    Sep 25, 2018
    20
    一个实例部分在栈上部分在堆上还真是常有的事。
    bumz
    bumz
    Sep 25, 2018
    21
    Object 在堆的时候在堆,Object 在栈的时候在栈

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

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

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

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

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