Posto corretto per eliminare oggetti dinamici

1

Esiste un componente software Processor che elabora gli oggetti Item in un thread dedicato. Item può essere elaborato più volte (in particolare, è un oggetto timer).

Uno dei campi di Item è un puntatore a BaseObject . Quindi tutte le classi derivate di BaseObject (ad esempio DerivedObject ) possono risiedere in Item . % istanze diItem vengono create in alcune parti del codice come SomeFunction() e aggiunte alla coda di elaborazione di Processor .

// Base class of objects that are passed around
class BaseObject {}

class DerivedObject : public BaseClass {}

// Unit of work
class Item {
    public:
        BaseObject * obj;
}

class Processor {
    std::vector<Item> items;
public:
    void AddItem(Item item);

    // Run in another thread and process items
    void Work() {
        ...
        SomeCallback(item.obj);
        ...
    }
}

Processor processor; // There is a single instance of the processor

void SomeFunction() {
    DerivedObject * dObject = new DerivedObject();
    Item item;
    item.obj = dObject;
    processor::AddItem(item);
}

Domande:

1) Quando e dove dovrei eliminare dObject ?

2) È un buon approccio copiare il contenuto di dObject mentre lo aggiungi a Item ?

Grazie per il tuo aiuto in anticipo!

    
posta Konstantin 17.03.2017 - 15:09
fonte

1 risposta

3

1) Mai. Né dovresti usarne una nuova per assegnarne una. Invece Item :: obj dovrebbe essere uno std :: unique_ptr. Quindi la durata dell'oggetto controlla la durata di DerivedObject e il polimorfismo è ancora

// Unit of work
class Item {
    public:
        // move an existing obj 
        Item(std::unique_ptr<BaseObject>&& obj) : obj(obj) {}
}

// helper function
template <typename Derived, typename ... Args>
Item make_item(Args ... args)
{ return Item(std::make_unique<Derived>(args...)); }

class Processor {
    std::vector<Item> items;
public:
    void AddItem(Item&& item);

    // Run in another thread and process items
    void Work() {
        ...
        SomeCallback(item.obj.get());
        SomeOtherCallback(*item.obj);
        ...
    }
}

void SomeFunction() {
    std::unique_ptr<BaseObject> item = std::make_unique<DerivedObject>(); // covariant assign
    processor::AddItem(std::move(item)); // move the item in
    processor::AddItem(Item(std::make_unique<DerivedObject>())); // also moves in, but from a temporary
    processor::AddItem(make_item<DerivedObject>()); // construct in place with template
}
    
risposta data 19.03.2017 - 22:18
fonte

Leggi altre domande sui tag