除了动态内存分配之外,以下两行代码之间是否有功能上的区别:
Time t (12, 0, 0); //t is a Time object
Time* t = new Time(12, 0, 0);//t is a pointer to a dynamically allocated Time object
我假设已经定义了一个Time(int, int, int)
构造函数。我也意识到在第二种情况下,t
需要被删除,因为它是在堆上分配的。还有其他区别吗?
除了动态内存分配之外,以下两行代码之间是否有功能上的区别:
Time t (12, 0, 0); //t is a Time object
Time* t = new Time(12, 0, 0);//t is a pointer to a dynamically allocated Time object
我假设已经定义了一个Time(int, int, int)
构造函数。我也意识到在第二种情况下,t
需要被删除,因为它是在堆上分配的。还有其他区别吗?
这行代码:
Time t (12, 0, 0);
该代码在本地作用域中分配了一个Time
类型的变量,通常在堆栈上,它的作用域结束时将被销毁。
相比之下:
Time* t = new Time(12, 0, 0);
通过调用::operator new()
或Time::operator new()
来分配一块内存,然后使用该内存块中地址(也作为new
的结果返回)设置this
,调用Time::Time()
构造函数,将其存储在t
中。通常情况下,这是在堆上完成(默认情况下),并需要在程序中稍后使用delete
进行删除,而t
中的指针通常存储在栈上。
注意:我的“通常”是指常见实现方式。C++标准不将栈和堆区别为机器的一部分,而是以它们的生存期为依据。局部范围内的变量被称为“自动存储期”,因此在局部范围结束时被销毁;使用new
创建的对象被称为“动态存储期”,仅在delete
后才会被销毁。从实际角度来看,这意味着自动变量在栈上创建和销毁,而动态对象存储在堆上,但这不是语言要求的。
t
是在本地范围内声明的“自动变量”。因此,它通常分配在堆栈上。但通常与讨论无关,因为它仅仅是指向Time
对象。 - greyfadeTime t (12, 0, 0);
在栈上创建的?我看了一个类似的问题,评论里有一些讨论(这里,这里和其余的评论线程),但我不明白他的意思。你能澄清一下吗? - yadav_viTime t (12, 0, 0);
t.GetTime();
Time* t = new Time(12, 0, 0);
t->GetTime();
就构造函数而言,这两种形式在功能上是相同的:它们只会导致构造函数在新分配的对象实例上被调用。你似乎已经对分配模式和对象生命周期的差异有了很好的掌握。
我认为你已经了解所有的差异。假设你已经很清楚通过指针和变量访问t成员的语法差异(好吧,指针也是一个变量,但我想你知道我的意思)。并且假设你知道在将t传递给函数时按值调用和按引用调用的区别。我相信你也明白如果你将t赋值给另一个变量,并通过那个其他变量进行更改会发生什么。结果将取决于t是否为指针。
调用operator new函数获取动态内存,然后调用构造函数。
不会调用operator new函数,直接调用构造函数。将直接使用栈,不需要使用malloc。
与你已知的没有其他区别。
假设你的代码使用默认的operator new服务。
在堆上分配对象和在栈上分配对象之间在功能上没有区别。两者都会调用对象的构造函数。
顺便提一下,我建议你在堆上分配时使用boost的shared_ptr或scoped_ptr,它们在功能上也是等效的(scoped_ptr还有额外的实用性,可以限制您复制不可复制的指针):
scoped_ptr<Time> t(new Time(12, 0, 0));
void foo (Time t)
{
t = Time(12, 0, 0);
}
void bar (Time* t)
{
t = new Time(12, 0, 0);
}
int main(int argc, char *argv[])
{
Time t;
foo(t);//t is not (12,0,0),its value depends on your defined type Time's default constructor.
bar(&t);//t is (12,0,0)
return 0;
}