Le mie domande riguardano come restituire un oggetto che non ha un costruttore di copie. Ad esempio immaginiamo di avere un po 'di bigResource
che si trova nell'heap, e diciamo che ne tengo traccia usando un unique_ptr
. Supponiamo ora di dare la proprietà di questa risorsa a un bruco. Allora ho un CaterpillarWithBigResource
. A un certo punto, questo CaterpillarWithBigResource
diventerà un ButterflyWithBigResource
, quindi l'oggetto Caterpillar
dovrà trasferire la proprietà all'oggetto Butterfly
.Come restituire un oggetto senza costruttore di copia
Ho scritto il seguente codice per modellare la situazione:
#include <cstdlib>
#include <iostream>
#include <memory>
class ButterflyWithBigResource {
public:
// If I uncomment just this line, I get an error
// ButterflyWithBigResource(const ButterflyWithBigResource& other) = default;
// If I uncomment just this line, I get an error
// ButterflyWithBigResource(const ButterflyWithBigResource& other) = delete;
// With both above lines commented out, I get no errors, and the program runs fine.
ButterflyWithBigResource(std::unique_ptr<int>&& bigResource) :
bigResource(std::move(bigResource)) {
}
const int& getResource() {
return *bigResource;
}
private:
std::unique_ptr<int> bigResource;
};
class CaterpillarWithBigResource {
public:
CaterpillarWithBigResource(int bigResource) :
bigResource(new int(bigResource)) {
}
ButterflyWithBigResource toButterfly() && {
return ButterflyWithBigResource(std::move(bigResource));
}
private:
std::unique_ptr<int> bigResource;
};
/*
*
*/
int main(int argc, char** argv) {
CaterpillarWithBigResource caterpillarWithBigResource(5);
ButterflyWithBigResource butterflyWithBigResource(std::move(caterpillarWithBigResource).toButterfly());
std::cout << butterflyWithBigResource.getResource() << std::endl;
return 0;
}
Si noti che né il Caterpillar
né il Butterfly
avere costruttori di copia predefinite, perché ognuno ha un unique_ptr
. Tuttavia, non mi aspetto che questo sia un problema, quindi è necessario solo spostare i costruttori. Dopotutto, trasferisco solo la proprietà dallo Caterpillar
allo Butterfly
.
Infatti quando compilo il programma con g++ -c -g -std=c++11 -MMD -MP -MF
utilizzando la versione g++
4.8.2
funziona perfettamente.
Ma ora la cosa strana è che se ricordo il compilatore che i Butterfly
's costruttore di copia viene eliminato aggiungendo la riga ButterflyWithBigResource(const ButterflyWithBigResource& other) = delete;
, il programma non viene compilato, e il compilatore si lamenta che costruttore di copia viene cancellato, in modo che io possa restituire Butterfly
nel metodo toButterfly
.
Se poi provo a dire che tutto è ok invece di avere la riga ButterflyWithBigResource(const ButterflyWithBigResource& other) = default;
, ho di nuovo lo stesso errore.
Quello che voglio che accada è per il Butterfly
costruito nel metodo toButterfly
di essere spostati in toButterfly
'indirizzo di ritorno s, e poi utilizzato come argomento di Butterfly
' costruttore mossa s quando si costruisce butterflyWithBigResource
in main()
. C'è un modo per farlo accadere?
BTW, per restituire un oggetto senza costruttore di copia, utilizza copy- list-initialization: 'return {std :: move (bigRes ource)} ' – 0x499602D2