削除を追加するまで、これらは同じではありません。
あなたの例は非常に些細なものですが、デストラクタには実際に実際の作業を行うコードが含まれている可能性があります。これはRAIIと呼ばれます。
したがって、削除を追加します。例外が伝播している場合でも、それが発生することを確認してください。
Pixel* p = NULL; // Must do this. Otherwise new may throw and then
// you would be attempting to delete an invalid pointer.
try
{
p = new Pixel();
p->x = 2;
p->y = 5;
// Do Work
delete p;
}
catch(...)
{
delete p;
throw;
}
ファイル(閉じる必要のあるリソース)のようなもっと面白いものを選んだ場合。次に、これを行うために必要なポインタを使用して、Javaで正しく実行します。
File file;
try
{
file = new File("Plop");
// Do work with file.
}
finally
{
try
{
file.close(); // Make sure the file handle is closed.
// Oherwise the resource will be leaked until
// eventual Garbage collection.
}
catch(Exception e) {};// Need the extra try catch to catch and discard
// Irrelevant exceptions.
// Note it is bad practice to allow exceptions to escape a finally block.
// If they do and there is already an exception propagating you loose the
// the original exception, which probably has more relevant information
// about the problem.
}
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.
他にもあります。