以下是一个例子:
while (i < 10)
{
int j = 1;
string k = "hello.";
}
j是原始数据类型,k是对象。根据{{3}},
所以非类类型(包括基本类型,数组类型, 引用类型,指针类型和枚举类型)没有 构造
根据Do built-in types have default constructors?,
构造函数和析构函数必须在每次迭代时执行 对象的情况(例如std :: string)。
然而,Declaring Variables inside Loops, good practice or bad practice? (2 Parter)说,
while(i--) { int i=100; // gets created every time the loop is entered i--; printf("%d..",i); } // the i in the loop keeps getting destroyed here
我已经了解到,当一个函数被调用时(例如操作系统的main()
),所有局部变量都是在函数开始时创建的,并在函数结束时被销毁。上面的while循环引用是说原始数据类型i
是在while循环块中声明时创建的,并且在每次迭代的while循环块结束时被销毁。
这是真的吗? #1 在while循环块中声明的原始数据类型是为while循环的每次迭代分配的吗? #2 我错误地认为while循环中的这些声明应该在函数的开头创建,而while循环块包含在?
中我正在寻找详细解释,而不仅仅是是或否。
答案 0 :(得分:3)
程序必须表现,好像每次循环都会重新分配(然后解除分配)。
程序展示该行为完全取决于编译器的机制。在许多情况下,根本不会为变量分配任何空间,或者甚至根本不存在空间! (例如第一个例子中的j
)
如果空间被分配,我认为通常在调用包含循环的函数时保留空间。 (并且该空间不一定完全保留)
答案 1 :(得分:3)
是的,当你在循环中声明一个变量时,程序的行为就好像变量是在每次循环迭代中创建和销毁的。因此,如果变量具有类类型,则程序的行为就像每次调用其构造函数和析构函数一样。
然而,由于优化,可以消除不可观察的行为,因此可以完全优化第一个循环,并且可以将第二个循环优化为类似
while(i--)
printf("%d..", 99);
因此可能会发生没有创建实际变量。
答案 2 :(得分:1)
逻辑上,是的,变量是在循环体的开始处为循环的每次迭代创建的,并在最后被销毁。
在你的第一个例子中,每次迭代都将调用std::string
(实际上std::basic_string<char>
是std::string
是什么)的构造函数,析构函数也是如此。同样地,j
正在创建并在每次迭代时设置为1
。
在第二个示例中,出于同样的原因,i
将使用值99
打印。
编译器确实有一些余地。如果他们能够检测到没有重复创建和销毁的效果,他们可以保持变量存活,并简单地为每次循环迭代重新初始化它。它们甚至可以完全消除变量(例如,只重复打印99,而不是创建变量)。但是,这样的事情是不可靠的,程序无法测试它是否发生。