为什么我的对象似乎不使用`new`就在堆上?

And*_*ony 3 c++ heap-memory dynamic-memory-allocation stack-memory

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

我有以下代码:

#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;
}
Run Code Online (Sandbox Code Playgroud)

#ifndef A_H_
#define A_H_

#include <iostream>
#include "B.h"

class A {
public:
   A();
   virtual ~A();

public:
   B b;
};

#endif /* A_H_ */
Run Code Online (Sandbox Code Playgroud)

#include "A.h"

A::A() {
   std::cout <<"Constructor A called" << std::endl;
}

A::~A() {
}
Run Code Online (Sandbox Code Playgroud)

#ifndef B_H_  
#define B_H_

#include <iostream>

class B {
public:
  B();
  virtual ~B();
};

#endif /* B_H_ */
Run Code Online (Sandbox Code Playgroud)

#include "B.h"

B::B() {
  std::cout <<"Constructor B called" << std::endl;
}

B::~B() {
}
Run Code Online (Sandbox Code Playgroud)

调试器的输出为:

临时断点6,main()位于../src/HeapStackTest02.cpp:18
18个A类

断点4,B.:B(this = 0x23aa58)位于../src/B.cpp:12
12 std :: cout <<“构造函数B被调用” << std :: endl;

../src/A.cpp:13处的断点5,A :: A(this = 0x23aa50)
13 std :: cout <<“构造函数A被调用” << std :: endl;

在../src/B.cpp:12处的断点4,B :: B(this = 0x23aa40)
12 std :: cout <<“构造函数B被调用” << std :: endl;

../src/B.cpp:12处的断点4,B :: B(this = 0x60004b048)
12 std :: cout <<“构造函数B被调用” << std :: endl;

../src/A.cpp:13处的断点5,A :: A(this = 0x60004b040)
13 std :: cout <<“构造函数A被调用” << std :: endl;

断点1,main()位于../src/HeapStackTest02.cpp:30
30返回0;

对我的问题:

b类的成员变量在哪里A

如果我查看0x23a部分中的地址,它似乎是堆栈,而0x6000部分似乎是堆。

我正在Windows 64位系统上工作。

为什么在b没有new调用运算符的情况下,成员变量也位于堆上?

Lig*_*ica 5

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

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

这就是为什么当您看到时应避免使用术语“堆上”的原因newnew“堆中” 不只是您自己的事情。不,new可以动态分配对象以及该对象直接包含的所有内容。在您编写对象的声明方式与“在堆上”还是“在堆上”之间的任何心理联系都注定会失败。

确定对象存储期限的唯一可靠方法是了解其历史记录。确定对象存储位置的唯一可靠方法是不必打扰,因为您不需要这样做。