我的代码片段如下,但是当我有2个自定义类并且我定义它们并打印它们的内存地址时:
for(int i=0;i<2;i++){
Engine b;
Strategy d;
std::cout<<"be:"<<&b<<std::endl;
std::cout<<"elm:"<<&d<<std::endl;
}
输出:
是:0x7ffd92aee2c0
榆树:0x7ffd92aede70
是:0x7ffd92aee2c0
榆树:0x7ffd92aede70
我期待两组不同的内存地址,但它们是相同的。有人能告诉我如何初始化到不同的地址吗?
答案 0 :(得分:3)
我期待两组不同的内存地址
没有理由期待这一点。到下一次迭代开始时,前一次迭代中自动对象的生命周期已经结束,因此下一次迭代中的对象可以重用相同的存储,即它可以具有相同的内存地址。
有人可以告诉我如何初始化到不同的地址吗?
您无法指定分配自动存储持续时间对象的内存位置。但是,如果您创建两个生命周期重叠的对象,则它们必须存储在不同的地址中。约翰已经在answer中使用数组展示了如何做到这一点。
答案 1 :(得分:2)
显而易见的方法是
Engine b[2];
Strategy d[2];
for(int i=0;i<2;i++){
std::cout<<"be:"<<&b[i]<<std::endl;
std::cout<<"elm:"<<&d[i]<<std::endl;
}
但真正的问题是你关心地址是否相同的原因。很可能它不是你需要担心的事情。
答案 2 :(得分:1)
您输出的两个变量应该只有1个唯一的内存地址,即等于
0x7ffd92aee2c0
输出了两次,没有任何变化。
然后
榆树:0x7ffd92aede70
是同样的情况,你输出两次没有变化,你期望有什么不同?
代码工作正常!
答案 3 :(得分:1)
每次进入块时都会创建块范围内创建的对象,并在每次阻止块时将其销毁。在循环的情况下,您的对象b
和d
将分别在迭代的每个开始和结束时创建和销毁。因此,每次迭代都会获得“新”对象,但编译器可以自由使用任何地址(甚至是用于先前迭代对象的地址),因此可能会一次又一次地看到相同的地址。但也可能会发生不同的情况。无论如何,依赖于生命时间已经结束/将要结束的对象的内存地址是没有意义的,所以更有趣的问题是:“为什么你关心e
和d
的内存地址?吗?”。
要了解会发生什么,请尝试以下代码。它显示了在程序过程中如何创建和销毁对象:
class TestClass {
public:
TestClass (int x=0) : x (x) { cout << "Constructing " << x << endl; };
TestClass (const TestClass& t) : x (t.x) { cout << "CopyConstructing " << x << endl; };
TestClass (const TestClass&& t) : x (t.x) { cout << "Moving " << x << endl; };
~TestClass () { cout << "Destructing " << x << endl; };
int x;
};
int main() {
for(int i=0;i<2;i++){
TestClass b(i);
std::cout<<"elm:"<<&b<<std::endl;
}
}
输出:
Constructing 0
elm:0x7fff5fbff780
Destructing 0
Constructing 1
elm:0x7fff5fbff780
Destructing 1