C ++:如何在循环内的堆栈上创建对象?

时间:2017-02-09 07:37:37

标签: c++ loops object

假设我有这样的代码: -

struct myStruct{

    int a;
    int b;
};

int main(){

    for(int i=0; i<5; i++){

        myStruct obj; 
        cout<<"Address of object in memory : "<<&obj<<endl;
    }

    return 0;
}

这是否实际上在堆栈上创建了5个不同的对象?如果是这样的话,为什么它每次打印完全相同的内存地址,因为obj是实际的对象而不是对象的引用?我在网站上已经阅读了一些答案,但我仍然无法完全理解它。

3 个答案:

答案 0 :(得分:2)

如果您打印出相同的地址,这只意味着重复使用内存空间,并不意味着它们是相同的对象。

如果添加用户定义的构造函数(和析构函数),您将看到构造(和销毁)5个不同的对象:

struct myStruct{

    myStruct() { std::cout << "ctor\n"; }
    ~myStruct() { std::cout << "dtor\n"; }

    int a;
    int b;
};

可能的结果:

ctor
Address of object in memory : 0x7fffc5be8c50
dtor
ctor
Address of object in memory : 0x7fffc5be8c50
dtor
ctor
Address of object in memory : 0x7fffc5be8c50
dtor
ctor
Address of object in memory : 0x7fffc5be8c50
dtor
ctor
Address of object in memory : 0x7fffc5be8c50
dtor

LIVE

答案 1 :(得分:1)

对象obj在每次迭代开始时创建,并在结束时销毁。

如果将输出语句放在其构造函数和析构函数中,您将能够看到发生这种情况。 (虽然从技术上讲,编译器可以自由地删除对象,如果检测它们存在的唯一方法是跟踪构造函数和析构函数调用,大多数编译器在这种情况下可能不会,因为替代方案将在开始时重新初始化对象。每次迭代)。

您还可以通过添加额外的范围来查看此内容。

int main()
{

   for(int i=0; i<5; i++)
   {
      {   // extra scope here
          myStruct obj; 
          cout<<"Address of object in memory : "<<&obj<<endl;
      }
      obj = something();   //   will not compile since obj does not exist here
   }

   return 0;
}

对于使用堆栈的编译器(实现细节,标准不要求),在一次迭代结束和下一次迭代开始之间,附加变量很可能不会放在堆栈上。这可以解释你看到所有对象具有相同的地址。

答案 2 :(得分:0)

这是否实际上在堆栈上创建了5个不同的对象

是的,它确实会创建5个不同的对象。它是否在堆栈上创建它是另一回事。 所有它说的是,在for循环的每次迭代中,将静态创建一个新对象。现在,当静态创建一个对象时,它具有预定义的范围和生命周期,该范围由编译时间本身。对于实例myStruct obj;,范围为for循环。在每次迭代中是否为实例获取相同或不同的地址是实现定义的。

此外,每个对象都有自己的身份,可以通过新创建的事实进行验证(如其他答案中所指定)。此外,此标识是由对象的范围,生命周期,名称组合定义的。现在,此标识不能是该对象的地址。