Why does my object appear to be on the heap without using `new`?
我开始学习动态内存分配的主题。
我有以下代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | #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; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | #ifndef A_H_ #define A_H_ #include <iostream> #include"B.h" class A { public: A(); virtual ~A(); public: B b; }; #endif /* A_H_ */ |
1 2 3 4 5 6 7 8 | #include"A.h" A::A() { std::cout <<"Constructor A called" << std::endl; } A::~A() { } |
1 2 3 4 5 6 7 8 9 10 11 12 | #ifndef B_H_ #define B_H_ #include <iostream> class B { public: B(); virtual ~B(); }; #endif /* B_H_ */ |
1 2 3 4 5 6 7 8 | #include"B.h" B::B() { std::cout <<"Constructor B called" << std::endl; } B::~B() { } |
调试器的输出是:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | Temporary breakpoint 6, main () at ../src/HeapStackTest02.cpp:18 18 A classAStack; Breakpoint 4, B::B (this=0x23aa58) at ../src/B.cpp:12 12 std::cout <<"Constructor B called" << std::endl; Breakpoint 5, A::A (this=0x23aa50) at ../src/A.cpp:13 13 std::cout <<"Constructor A called" << std::endl; Breakpoint 4, B::B (this=0x23aa40) at ../src/B.cpp:12 12 std::cout <<"Constructor B called" << std::endl; Breakpoint 4, B::B (this=0x60004b048) at ../src/B.cpp:12 12 std::cout <<"Constructor B called" << std::endl; Breakpoint 5, A::A (this=0x60004b040) at ../src/A.cpp:13 13 std::cout <<"Constructor A called" << std::endl; Breakpoint 1, main () at ../src/HeapStackTest02.cpp:30 30 return 0; |
我的问题是:
如果我查看0x23A节中的地址,它似乎是堆栈,而0x6000节似乎是堆。
我正在使用Windows 64位系统。
为什么成员变量
成员是
如果成员不是对象的一部分,还剩下什么?您将动态分配什么?
这就是当您看到
确定对象的存储持续时间的唯一可靠方法是了解其历史记录;确定对象存储位置的唯一可靠方法是不用麻烦,因为您不需要这样做。
要回答这个问题,我们首先要了解我们有多少B类型的实例。答案是3。
一个实例是类型A(堆栈上)的成员B。另一个是堆栈上B的实例,第三个是堆上A类型的成员B的实例。
为什么要堆起来?它就在那里,因为您在堆上创建了类型A的实例,而A的实例将B的实例作为成员。
所以B的3个实例中的一个在堆上,另2个在堆栈上。
考虑一下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | #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; } |