Supponiamo che ho una classe che gestisce un puntatore a un buffer interno:Spostare la semantica con un puntatore a un buffer interno
class Foo
{
public:
Foo();
...
private:
std::vector<unsigned char> m_buffer;
unsigned char* m_pointer;
};
Foo::Foo()
{
m_buffer.resize(100);
m_pointer = &m_buffer[0];
}
Ora, supponiamo che io anche hanno attuato correttamente roba regola-of-3 tra cui una copia costruttore che copia il buffer interno, e quindi riassegna il puntatore alla nuova copia del buffer interno:
Foo::Foo(const Foo& f)
{
m_buffer = f.m_buffer;
m_pointer = &m_buffer[0];
}
Se anche implementare semantica spostare, è sicuro di basta copiare il puntatore e spostare il buffer?
Foo::Foo(Foo&& f) : m_buffer(std::move(f.m_buffer)), m_pointer(f.m_pointer)
{ }
In pratica, so che questo dovrebbe funzionare, poiché il costruttore std::vector
mossa è solo muovendo il puntatore interno - non è in realtà una ridistribuzione niente di così m_pointer
ancora punta a un indirizzo valido. Tuttavia, non sono sicuro che lo standard garantisca questo comportamento. La semantica di spostamento std::vector
garantisce che non si verificherà alcuna riallocazione e quindi tutti i puntatori/iteratori del vettore sono validi?
So che 'swap' garantisce che i puntatori saranno ancora validi, ma non sono sicuro delle mosse. –
C'è stata una discussione molto lunga su questi problemi su una [domanda correlata] (http://stackoverflow.com/q/17730689/1782465). Credo che la conclusione sia che in un agente di movimento, il buffer è garantito per essere appena trasferito. In un'operazione di assegnazione di spostamento, può accadere (in base alle proprietà di allocatore) che il buffer verrà copiato. – Angew
Non dovresti fare 'f.m_pointer = nullptr;' nel corpo del costruttore di move? Perché indicare un indirizzo che non è i suoi fratelli? Se hai un accoppiamento tra due variabili che è piuttosto stretto, direi di tenerlo così, invece di fare un cross coupling. – legends2k