ho trovato strano comportamento di un codice che apparentemente ignorando const-ness:restituendo l'oggetto di costante e assegnandolo alla non costante oggetto
#include <iostream>
using std::cerr;
class A
{
public:
A() { cerr << "A::A()\n"; }
A(const A &a) { cerr << "A::A(const A&)\n"; }
A(A &&) { cerr << "A::A(A&&)\n"; }
A & operator = (const A &a) { cerr << "A::operator=(const A&)\n"; return *this; }
A & operator = (A &&a) { cerr << "A::operator(A&&)\n"; return *this; }
~A() { cerr << "A::~A()\n"; }
const A get() const { cerr << "const A A::get() const\n"; return A(); }
A get() { cerr << "A A::get()\n"; return A(); }
};
int main()
{
const A a;
A b = a.get();
}
In primo luogo, quello che mi aspettavo qui: a
è una costante , quindi viene invocata la versione costante di get(). Successivamente, viene restituito l'oggetto costante, ma sul lato sinistro è l'oggetto non costante b
, quindi è necessario chiamare il costruttore di copia. Quale non è:
A::A()
const A A::get() const
A::A()
A::~A()
A::~A()
Questo comportamento è previsto dallo standard C++? Quindi, è giusto che la costanza di un oggetto temporaneo venga semplicemente ignorata da RVO? E come si potrebbe applicare la copia qui?
uscita con copia-elision disabilitata (-fno-elide-constructors
) fa una mossa ulteriore e la chiamata costruttore di copia atteso:
A::A()
const A A::light_copy() const
A::A()
A::A(A&&)
A::~A()
A::A(const A&)
A::~A()
A::~A()
A::~A()
Se a
oggetto non è costante, allora sarà due mosse senza copiare, che è previsto anche.
PS. Il comportamento è importante per me perché quello che vedo è la violazione della rigidità di copia superficiale: per la versione const di get()
(che è in realtà shallow_copy()
), devo essere sicuro che non verrà apportata alcuna modifica dell'oggetto restituito, perché il reso restituisce l'oggetto è una copia superficiale e una modifica sulla copia superficiale influenzerà l'oggetto "genitore" (che potrebbe essere una costante).
ottimizzazione Restituire il valore (RVO) in azione. – Jarod42
BTW, vedi [dovrebbe-i-ancora-return-const-objects-in-c11] (http://stackoverflow.com/questions/13099942/should-i-still-return-const-objects-in-c11) – Jarod42
Con "light_copy", intendi "copia superficiale"? –