2015-04-20 17 views
8

E 'facile fare di classe noncopyable con copia privata construcor e operatore di assegnazione, boost::noncopyable o il C++ 11 delete parola chiave:Posso impedire che l'oggetto venga copiato da std :: memcpy?

class MyClass { 
private: 
    int i; 
public: 
    MyClass(const MyClass& src) = delete; 
    MyClass& operator=(const MyClass& rhs) = delete;  
    int getI() { 
     return i; 
    } 
    MyClass(int _i) : i(_i){} 
}; 

int main() { 
    MyClass a(1), b(2); 
    a = b; // COMPILATION ERROR 
} 

Tuttavia questo non impedisce obiect dall'essere profondo copiato come un pacchetto di byte:

int main() { 
    MyClass a(1), b(2); 
    std::memcpy(&a, &b, sizeof(MyClass)); 
    std::cout << a.getI() << std::endl; // 2 
} 

Anche se cercare di evitare che dichiarando operator& privata, è ancora possibile fare copia utilizzando implementazioni di indirizzo-di linguaggio:

int main() { 
    MyClass a(1), b(2); 
    std::memcpy(std::addressof(a), std::addressof(b), sizeof(MyClass)); 
    std::cout << a.getI() << std::endl; // 2 
} 

Esiste un metodo per impedire completamente che un'istanza venga copiata byte per byte?

+5

Dubito seriamente che sia possibile. –

+7

La memcpy non sa nulla degli oggetti C++ e non gli importa. È un toro in un negozio di porcellana - non puoi impedirgli di fare quello che fa. Arriva un momento in cui devi credere che i programmatori che usano le tue classi sanno cosa stanno facendo. – PaulMcKenzie

+1

La domanda è: perché vuoi impedirlo? – MikeMB

risposta

8

È possibile impedire che l'oggetto venga copiato da std::memcpy?

La risposta semplice è "No".

0

Questo non è a prova di proiettile ma è possibile implementare il proprio memcpy_safe che si comporta in modo simile ma accetta qualcos'altro di void*. Quindi crei un file include che contiene

#define memcpy memcpy_old 
#include <cstring> 
#undef memcpy 
#define memcpy memcpy_safe 

E dire alle persone di utilizzare questo file di inclusione. Quello che fa è nascondere la dichiarazione di memcpy e sostituisce tutte le chiamate a memcpy con le chiamate a memcpy_safe. La nuova funzione deve essere implementata nella propria unità di traduzione, quindi è possibile chiamare il vecchio memcpy.

Problemi correlati