Orang lain telah membahas masalah lain, jadi saya hanya akan melihat satu hal: apakah Anda pernah ingin menghapus objek secara manual.
Jawabannya iya. @DavidSchwartz memberi satu contoh, tapi itu cukup satu tidak biasa. Saya akan memberikan contoh yang ada di balik terpal dari apa yang banyak digunakan programmer C ++ sepanjang waktu: std::vector(dan std::deque, meskipun tidak terlalu banyak digunakan).
Seperti yang diketahui kebanyakan orang, std::vectorakan mengalokasikan blok memori yang lebih besar ketika / jika Anda menambahkan lebih banyak item daripada yang dapat ditampung oleh alokasi saat ini. Namun, ketika melakukan ini, ia memiliki blok memori yang mampu menampung lebih banyak objek daripada yang ada di vektor.
Untuk mengelolanya, apa yang vectordilakukan di bawah selimut adalah mengalokasikan memori mentah melalui Allocatorobjek (yang, kecuali Anda menentukan sebaliknya, berarti digunakannya ::operator new). Kemudian, saat Anda menggunakan (misalnya) push_backuntuk menambahkan item ke vector, secara internal vektor menggunakan a placement newuntuk membuat item di bagian ruang memorinya (yang sebelumnya) tidak terpakai.
Sekarang, apa yang terjadi jika / jika Anda erasemerupakan item dari vektor? Itu tidak bisa begitu saja delete- itu akan melepaskan seluruh blok memorinya; ia perlu menghancurkan satu objek dalam memori itu tanpa merusak yang lain, atau melepaskan salah satu blok memori yang dikendalikannya (misalnya, jika Anda erase5 item dari vektor, lalu segera push_back5 item lagi, dijamin bahwa vektor tidak akan dialokasikan kembali memori saat Anda melakukannya.
Untuk melakukan itu, vektor secara langsung menghancurkan objek dalam memori dengan secara eksplisit memanggil destruktor, bukan dengan menggunakan delete.
Jika, mungkin, ada orang lain yang menulis wadah menggunakan penyimpanan yang berdekatan secara kasar seperti yang vectordilakukan (atau beberapa varian dari itu, seperti yang std::dequesebenarnya), Anda hampir pasti ingin menggunakan teknik yang sama.
Sebagai contoh, mari pertimbangkan bagaimana Anda dapat menulis kode untuk buffer cincin melingkar.
#ifndef CBUFFER_H_INC
#define CBUFFER_H_INC
template <class T>
class circular_buffer {
T *data;
unsigned read_pos;
unsigned write_pos;
unsigned in_use;
const unsigned capacity;
public:
circular_buffer(unsigned size) :
data((T *)operator new(size * sizeof(T))),
read_pos(0),
write_pos(0),
in_use(0),
capacity(size)
{}
void push(T const &t) {
// ensure there's room in buffer:
if (in_use == capacity)
pop();
// construct copy of object in-place into buffer
new(&data[write_pos++]) T(t);
// keep pointer in bounds.
write_pos %= capacity;
++in_use;
}
// return oldest object in queue:
T front() {
return data[read_pos];
}
// remove oldest object from queue:
void pop() {
// destroy the object:
data[read_pos++].~T();
// keep pointer in bounds.
read_pos %= capacity;
--in_use;
}
~circular_buffer() {
// first destroy any content
while (in_use != 0)
pop();
// then release the buffer.
operator delete(data);
}
};
#endif
Berbeda dengan wadah standar, ini menggunakan operator newdan operator deletelangsung. Untuk penggunaan nyata, Anda mungkin ingin menggunakan kelas pengalokasi, tetapi untuk saat ini akan melakukan lebih banyak hal untuk mengalihkan perhatian daripada berkontribusi (bagaimanapun juga, IMO).