C++中的对象实例化方法
这两个实例化和方法调用类型有什么区别?C++中的对象实例化方法
采取此代码为例如:
class Test
{
public:
Test(int nrInstance)
{
std::cout << "Class " << nrInstance << " instanced " << std::endl;
}
~Test() { }
int retornaValue()
{
return value;
}
private:
const int value = 10;
};
int main(int argc, char *argv[])
{
Test *test1 = new Test(1);
Test test2(2);
std::cout << test1->retornaValue() << std::endl;
std::cout << test2.retornaValue() << std::endl;
return 0;
}
从什么IVE读,使用所述第一方式中,变量是在堆上分配,并且第二,在堆栈中,但的arent两者Main
范围内,并在函数退出后解除分配?
此外,两种示例中的调用方法都不相同,为什么?
您的权利这两个变量都在Main
范围和功能退出后释放,但在第一种情况下它是Test*
值被释放,而不是Test
实例本身。一旦指针解除分配,类实例就会泄露。在第二种情况下,Test
实例位于堆栈上,因此实例本身已解除分配。
此外,调用方法在两个示例中都不相同,为什么?
除非超载,foo->bar
相当于(*foo).bar
。调用语法不同,因为在第一种情况下,test1
是指向实例的指针,而第二种情况下,test2
是一个实例。
但不是都在主范围内,并在 函数退出后被释放?
完全没有...... * test1在你调用delete
之前不会被释放。
你不是指'test1'吗? – 2014-11-05 00:02:50
但都没有在主范围内,并在函数退出后被释放?
随着作用域关闭并释放,栈实例解除展开。指针也是,但它指向的对象不是。您必须明确delete
实例分配与new
。
在第一个示例中,您正在创建一个指向堆栈上的对象的指针,以及堆中的对象本身。
在第二个示例中,您正在堆栈上创建对象本身。
语法区别是通过指针调用函数并直接在对象上调用函数的区别。
对于正在清理的第一个示例,在指针超出范围之前需要一个delete
或者出现所谓的内存泄漏,这是错误的。当程序退出时,操作系统会清理内存泄漏,但最好的做法是避免它们。
感谢您的回复。对此有没有“最佳实践”?像什么时候使用一个或另一个? – Leandragem 2014-11-05 00:06:37
@Leandragem使用本地(堆栈)对象,除非您需要该对象的生存期超出当前块的存在,或者如果您将该对象的所有权传递给其他人。或者有时如果你需要一个不适合堆叠的大对象或数组,例如数百万的元素。 – 2014-11-05 00:08:38
你已经清楚地说明了你的问题的不同之处,一个在堆栈上,另一个在堆上。是的,当main()
退出时,它将被释放。现在让我们采取不同的方法。
#include <iostream>
using namespace std;
class MemoryLeak{
private:
int m_instance
public:
MemoryLeak(int i) : m_instance(i)
{ cout << "MemoryLeak " << i << " created.\n"; }
~MemoryLeak() { cout << "MemoryLeak " << m_instance << " deleted.\n"; }
};
void makeMemoryLeak(){
static int instance = 0
MemoryLeak mem1(++instance);
MemoryLeak* mem2 = new MemoryLeak(++instance);
}
int main(){
for(int x = 0; x < 10; ++x){
makeMemoryLeak();
cout << endl;
}
cin.get(); // Wait to close
return 0;
}
您将看到20个“创建新的MemoryLeak”。只有10行“MemoryLeak deleted”行。所以其他10个实例仍然在内存中,直到您关闭程序。现在让我们说,该程序永远不会关闭,并且MemoryLeak具有20个字节的大小。和makeMemoryLeak()
每分钟运行一次。在一天或1440分钟后,您将拥有28.125 kb的内存,但您无法访问。
的解决办法是改变makeMemoryLeak()
void makeMemoryLeak(){
MemoryLeak mem1;
MemoryLeak* mem2 = new MemoryLeak();
delete mem2;
}
关于什么被创建和销毁:
struct Test {};
void func()
{
// instantiate ONE automatic object (on the stack) [test1]
Test test1;
// Instantiate ONE automatic object (on the stack) [test2]
// AND instantiate ONE object from the free store (heap) [unnamed]
Test* test2 = new Test; // two objects!!
} // BOTH automatic variables are destroyed (test1 & test2) but the
// unnamed object created with new (that test2 was pointing at)
// is NOT destroyed (memory leak)
,如果你不出来的主之前删除的Test1(测试*),就会造成内存泄漏。
感谢编辑@remyabel,这种方式更好,它避免了混淆。 – Leandragem 2014-11-05 00:02:11
你似乎对C++的理解很少。在问这样的超级基本问题之前,你应该先做一些研究或读一本书。这是C++ 101 – Falmarri 2014-11-05 00:02:59
那么你是对的。我是C++的新手,但在继续下一步之前,我试图更好地理解这些主题。你会推荐一个很好的C++阅读材料吗? – Leandragem 2014-11-05 00:04:18