Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Dubbio dichiarazione unique_ptr

24 views
Skip to first unread message

Emanuele Merlo

unread,
Dec 12, 2017, 4:07:40 AM12/12/17
to
Mi trovo in un caso reale che posso semplificare così:


Pippo
{
/* ... vari costruttori e metodi */

Pippo* Clona() { return new Pippo(*this); }
}


void Funzione(Pippo* p1)
{
auto p1_ptr = std::make_unique<Pippo>(p1->Clona()); // dichiarazione #1

/* oppure */

auto p1_ptr = std::make_unique<Pippo*>(p1->Clona()); // dichiarazione #2
}


Qual è la dichiarazione corretta?

Emanuele Merlo

unread,
Dec 12, 2017, 4:16:19 AM12/12/17
to
Il giorno martedì 12 dicembre 2017 10:07:40 UTC+1, Emanuele Merlo ha scritto:

> Qual è la dichiarazione corretta?

e se fosse:

auto p1_ptr = std::make_unique</*?*/>(new Pippo());

?

enoquick

unread,
Dec 12, 2017, 10:35:53 PM12/12/17
to
Nessuna delle due



class pippo {
public:
using unique_pointer_type=std::unique_ptr<pippo>;
unique_pointer_type clone()const { return unique_pointer_t(new
pippo(*this);}
private:
pippo(const pippo&) ....
};

quest perche la funzione clone e' costante e deve dare come risultato un
unique pointer in modo che l'ulizzatore della classe non debba
ricordarsi di usare delete

Mai fare fuoriuscire un pointer nudo e crudo che l'utilizzatore deve
liberare con delete
E' una pessima progettazione.

Altra cosa,il metodo clone in questo caso non serve a molto (basta un
normale copy constructor)
Di solito e' utile se si usa l'ereditarieta' in modo da avere un copy
constructor virtuale (ed eventualmente anche un costruttore virtuale)


class base {
public:
using unique_pointer_type=std::unique_ptr<base>;
static unique_pointer_type make_instance(); //costruisce una classe
derivata da base in base ad alcune condizioni
virtual unique_pointer_type clone()const ...
protected:
base() ...
base(const base&) ..
};

class der : public base {
public:
unique_pointer_type clone()const override { return
unique_pointer_type(new der(*this);}
protected:
der(const der&) ...
private:
der() ...
friend unique_pointer_type base::make_instance();
};


class der1 : public base ...

class der2 : public base ...

fma...@gmail.com

unread,
Dec 12, 2017, 11:09:51 PM12/12/17
to
On Tuesday, December 12, 2017 at 4:07:40 AM UTC-5, Emanuele Merlo wrote:
> Mi trovo in un caso reale che posso semplificare così:
> <snip>
> Qual è la dichiarazione corretta?

A me pare un po' convoluto...
- perché non chiamare il semplice costruttore di copia?
- se vuoi un puntatore unico, perché non fare un singleton?

Ciao!

Emanuele Merlo

unread,
Dec 13, 2017, 3:39:08 AM12/13/17
to
Il giorno mercoledì 13 dicembre 2017 04:35:53 UTC+1, enoquick ha scritto:

> quest perche la funzione clone e' costante e deve dare come risultato un
> unique pointer in modo che l'ulizzatore della classe non debba
> ricordarsi di usare delete

Non ho giurisdizione sulla classe che implementa il "Clona", è un tipo variant personalizzato che arriva da una libreria ed è purtroppo implementato nel modo che ho descritto.
Io sto cercando di rendere la gestione di quel puntatore un minimo più sicura, perché è fonte di memory leaks.

> Mai fare fuoriuscire un pointer nudo e crudo che l'utilizzatore deve
> liberare con delete
> E' una pessima progettazione.

Sono d'accordo.

> Altra cosa,il metodo clone in questo caso non serve a molto (basta un
> normale copy constructor)
> Di solito e' utile se si usa l'ereditarieta' in modo da avere un copy
> constructor virtuale (ed eventualmente anche un costruttore virtuale)

Non so perché sia stata fatta questa scelta. L'implementazione reale è una famiglia di classi che ereditano da un'interfaccia base e implementano una trentina di tipi diversi. Ci sarà qualche motivo architetturale (che non arrivo a comprendere) o un'eredità del passato.

Grazie per la risposta.
0 new messages