为什么我的对象似乎在不使用new”的情况下在堆上

Why does my object appear to be on the heap without using `new`?

本文关键字:new 情况下 对象 我的 为什么      更新时间:2023-10-16

我开始学习动态内存分配的主题。

我有以下代码:

#include <iostream>
#include "A.h"
#include "B.h"
using namespace std;
int main() {
   /* Both objects on Stack */
   A classAStack;
   B classBStack;
   /* Both objects on Heap*/
   //  A *classAHeap = new A();
   //  B *classBHeap = new B();
   /* A objects on Heap B ???*/
   A *classAHeap = new A();
   return 0;
}

#ifndef A_H_
#define A_H_
#include <iostream>
#include "B.h"
class A {
public:
   A();
   virtual ~A();
public:
   B b;
};
#endif /* A_H_ */

#include "A.h"
A::A() {
   std::cout <<"Constructor A called" << std::endl;
}
A::~A() {
}

#ifndef B_H_  
#define B_H_
#include <iostream>
class B {
public:
  B();
  virtual ~B();
};
#endif /* B_H_ */

#include "B.h"
B::B() {
  std::cout <<"Constructor B called" << std::endl;
}
B::~B() {
}

调试器的输出是:

临时断点6,main((at ../src/heapstacktest02.cpp:1818 classastack;断点4,b :: b(this = 0x23aa58(at ../src/b.cpp:1212 std :: cout&lt;&lt;" constructor b chater"&lt;&lt;std :: endl;断点5,a :: a(this = 0x23aa50(at ../src/a.cpp:1313 std :: cout&lt;&lt;" constructor a nath&lt;&lt;std :: endl;断点4,b :: b(this = 0x23aa40(at ../src/b.cpp:1212 std :: cout&lt;&lt;" constructor b chater"&lt;&lt;std :: endl;断点4,b :: b(this = 0x60004b048(at ../src/b.cpp:1212 std :: cout&lt;&lt;" constructor b chater"&lt;&lt;std :: endl;断点5,a :: a(this = 0x60004b040(at ../src/a.cpp:1313 std :: cout&lt;&lt;" constructor a nath&lt;&lt;std :: endl;断点1,main((at ../src/heapstacktest02.cpp:3030返回0;

我的问题:

A类的成员变量b在哪里?

如果我查看第0x23a节中的地址,它似乎是堆栈,并且第0x6000节似乎是堆。

我正在使用Windows 64位系统。

为什么会员变量的b也在堆上,而没有称为new操作员?

成员是b是您动态分配的对象的一部分,因此它是该动态分配的一部分,并且位于内存中的同一位置。

如果成员不是对象的一部分,剩下什么?您将有什么动态分配?

这就是为什么当您看到new时避免术语"在堆上"的原因。"堆在堆上"不仅是您new的事情。不,new动态分配一个对象以及对象直接包含的所有内容。您编写对象的声明与它是"在堆上"或"堆栈上"是否注定要失败之间的任何精神关联。

确定对象存储持续时间的唯一可靠方法是了解其历史记录。确定对象存储位置的唯一可靠方法是不要打扰。

要回答这个问题,让我们开始找出我们拥有多少个B类实例。答案是3。

一个实例是A型的成员B(在堆栈上(。另一个是堆栈上B的实例,第三个是A型A类型B的成员B的实例。

为什么要堆?它在那里,因为您在堆上创建了类型A的实例,并且A的实例是B作为成员的实例。

所以B的3个实例之一在堆上,另外2个在堆上。

考虑以下内容:

#include <iostream>
#include <string>
class B {
public:
    int64_t x = 42;
    int64_t y = 7;
};
class A1 {
public:
    B b;
};
class A2 {
public:
    A2() { b = new B(); }
    B* b;
    ~A2() { delete b; }
};
int main() {
    std::cout << sizeof(A1) << std::endl;   // prints 16
    std::cout << sizeof(A2) << std::endl;   // prints 8
    // Section (2)
    A1 a1;  // Instance of A1 and B are on the stack
    A2 a2;  // Instance of A2 is on the stack. B is on the heap.
    A1* a3 = new A1();
    std::cout << a3 == &(a3->b) << std:: endl;  // prints true
    A2* a4 = new A2();
    std::cout << a4 == a4->b << std::endl;  // prints false
    return 0;
}   
相关文章: