Saya agak bingung w.r.t. penggunaan delete dan pembuatan objek baru. Katakanlah saya memiliki kelas yang menyimpan pointer ke beberapa objek lain dalam sebuah array:

#include <array>
#include "someObject.hpp"
class someContainer() {
    std::array<someObject*, 10> objects;
    void set_object(int n);
}

Apa cara terbaik untuk membuat dan menyimpan instance someObject dalam fungsi set_object yang tidak melibatkan penggunaan smart pointer atau pembungkus lainnya.

Sebagai contoh, saya percaya bahwa...

void someContainer::set_object(n) {
    // Some check that 0 < n < 9
    ...
    //=====
    someObject object* = &someObject(constructor_param);
    objects[n] = object;
}

... akan menghasilkan perilaku yang tidak terdefinisi, karena destruktor referensi object dipanggil saat fungsi keluar.

Kalau begitu, apakah cara yang benar adalah seperti ini?

void someContainer::set_object(n) {
    // Some check that 0 < n < 9
    ...
    //=====
    someObject object* = new someObject(constructor_param);
    objects[n] = object;
}

void someContainer::~someContainer() {
    int len = objects.size
    for (int i=0; i < len; i++) {
        delete objects[i];
    }

Atau apakah ada perilaku tidak terdefinisi di suatu tempat yang saya lewatkan? (Juga, saya pikir seseorang tidak boleh mengulangi array sambil juga menghapus objek darinya, itulah sebabnya saya menggunakan indeks len. Apakah ini benar?) Saya bertanya di sini karena semuanya dikompilasi dan tampaknya bekerja dengan baik, tetapi saya sulit mengetahuinya.

0
AmagicalFishy 28 Maret 2020, 00:48

1 menjawab

Jawaban Terbaik

Ini adalah masalah penting dalam manajemen memori: siapa yang memiliki nilai yang dialokasikan, mis. e. siapa yang bertanggung jawab untuk membebaskannya. Jika Anda menelepon

object[n] = new someObject(constructor_param);

Dan sudah ada objek yang disimpan di sana, objek lama akan tetap berada di suatu tempat di heap, mungkin tanpa petunjuk yang tersisa, jadi tidak akan pernah bisa dibebaskan lagi.

Anda mungkin ingin setter Anda terlihat seperti ini:

someObject *someContainer::set_object(n) {
    // Some check that 0 < n < 9
    ...
    //=====
    someObject *previous = objects[n];
    objects[n] = new someObject(constructor_param);
    return previous;
}

Untuk memberi sinyal kepada pengguna fungsi bahwa ia perlu menangani objek sebelumnya, baik delete segera atau menyimpannya di suatu tempat.

Selain itu, Anda sepenuhnya bebas untuk delete objek dalam loop reguler: ingat bahwa Anda hanya membebaskan objek yang ditunjuk oleh elemen array, dan tidak mengubah array sama sekali.

1
Remy Lebeau 27 Maret 2020, 22:10