只有在添加删除(delete)后它们才是相同的。
虽然您的示例过于简单,但析构函数实际上可能包含执行一些真正工作的代码。这被称为RAII。
因此,请添加删除操作确保即使异常正在传播也会被执行。
Pixel* p = NULL;
try
{
p = new Pixel();
p->x = 2;
p->y = 5;
delete p;
}
catch(...)
{
delete p;
throw;
}
如果你选择了像文件这样更有趣的资源(需要关闭的资源),那么在Java中使用指针时需要正确处理。
File file;
try
{
file = new File("Plop");
}
finally
{
try
{
file.close();
}
catch(Exception e) {};
}
同样的代码,但是使用C++
std::fstream file("Plop");
// Do work with file.
// Destructor automatically closes file and discards irrelevant exceptions.
虽然人们提到速度(因为在堆上查找/分配内存),但就我个人而言,这并不是决定性因素(分配器非常快速,并且已经针对C++使用小对象进行了优化,这些对象经常被创建/销毁)。
我更关注的是对象的生命周期。局部定义的对象具有非常特定和明确定义的生命周期,并且析构函数保证在最后调用(因此可以具有特定的副作用)。另一方面,指针控制具有动态寿命的资源。
C++和Java的主要区别在于:
指针归属的概念。拥有者有责任在适当的时候删除对象。这就是为什么你很少在真正的程序中看到像那样的原始指针(因为没有与原始指针相关联的所有权信息)。相反,指针通常包装在智能指针中。智能指针定义了内存所有者的语义,因此谁负责清理它。
例子如下:
std::auto_ptr<Pixel> p(new Pixel);
// An auto_ptr has move semantics.
// When you pass an auto_ptr to a method you are saying here take this. You own it.
// Delete it when you are finished. If the receiver takes ownership it usually saves
// it in another auto_ptr and the destructor does the actual dirty work of the delete.
// If the receiver does not take ownership it is usually deleted.
std::tr1::shared_ptr<Pixel> p(new Pixel); // aka boost::shared_ptr
// A shared ptr has shared ownership.
// This means it can have multiple owners each using the object simultaneously.
// As each owner finished with it the shared_ptr decrements the ref count and
// when it reaches zero the objects is destroyed.
boost::scoped_ptr<Pixel> p(new Pixel);
// Makes it act like a normal stack variable.
// Ownership is not transferable.
还有其他的。