Automatically generated move operations and raw pointing elements

Consider the MemoryMappedFile class with the following data members:

 class MemoryMappedFile { .... private: // RAII wrapper to some OS-specific raw handle (eg Win32 HANDLE), // representing the memory-mapped file. Handle m_handle; // Pointer to file begin (first file byte). BYTE* m_first; // Pointer to file end (one byte past last file byte). BYTE* m_last; }; 

The Handle class is some kind of RAII wrapper for some specific raw OS handle descriptor (for example, think of a Win32 Handle ). It cannot be copied, but is available for moving.
Instead, m_first and m_last are raw pointers inside the memory area displayed with the contents of the file.

I would like the MemoryMappedFile class MemoryMappedFile be movable (but not MemoryMappedFile like the Handle class).

If it weren’t for the original pointers, according to the rules for automatically generating the C ++ 11 move constructor using element moves, the class will automatically be moved.

Unfortunately, the source pointers force me to write my own move constructor:

 MemoryMappedFile::MemoryMappedFile(MemoryMappedFile&& other) : m_handle( std::move(other.m_handle) ) { // Move m_first m_first = other.m_first; other.m_first = nullptr; // Move m_last m_last = other.m_last; other.m_last = nullptr; } 

It would be nice if the C ++ standard library had some kind of dumb-as-against-smart pointer but movable pointer with zero overhead, as well as raw pointers (which are good, like observing pointers not related to owners), but with certain move operations (constructor move and move destination), so that the compiler can automatically generate the correct move operations in classes in which these pointers are data members.

Is there something similar in the C ++ standard library or in Boost?

Or is there another way to achieve the same goal (besides writing your own custom class, ObservingPointer, wrapping raw pointers and defining move operations)?

+1
source share
2 answers

I often need a smart pointer that is both copyable and movable, but has a well-defined moved state, so I wrote tidy_ptr , which is a dumb smart pointer that does nothing special except zero itself. This type is copyable, so to get the semantics you want for your class, you still need to define the copy operations as remote (or just use std::unique_ptr with no-op removed).

I tried to convince the standards committee that observer_ptr , the “dumbest smart pointer of the world," should have this behavior, but the consensus was that it should behave exactly like the built-in pointer (except for zero initialization in the constructor). I still think he should move to zero. This article shows non_owning_ptr , which is an alias for unique_ptr with a missing statement that does what you want.

+2
source

Just use std::unique_ptr with your noop_deleter .

+4
source

All Articles