Back on my crazy AutoArray thingy… (quoting important bits from there:
class AutoArray
{
void * buffer;
public:
//Creates a new empty AutoArray
AutoArray();
//std::auto_ptr copy semantics
AutoArray(AutoArray&); //Note it can't be const because the "other" reference
//is null'd on copy...
AutoArray& operator=(AutoArray);
~AutoArray();
//Nothrow swap
// Note: At the moment this method is not thread safe.
void Swap(AutoArray&);
};
)
Anyway, trying to implement the copy constructor. There’s a piece of client code (not yet committed into bitbucket because it won’t build) that looks like this:
AutoArray NtQuerySystemInformation(...) { ... };
AutoArray systemInfoBuffer = NtQuerySystemInformation(...);
This fails because the copy constructor takes a non-const reference as an argument …. but I don’t see how you could modify the copy constructor to take a const reference, given that the source AutoArray used in the assignment is modified (and therefore wouldn’t be const). You can’t modify things to use pass by value of course, because it’s the copy constructor and that’d be an infinite loop!
If I was using auto_ptr, this would be valid:
std::auto_ptr NtQuerySystemInformation(...) { ... };
std::auto_ptr systemInfoBuffer = NtQuerySystemInformation(...);
How then, can a class with auto_ptr‘s copy semantics be possible?
auto_ptruses a dirty trick.I’ll use a dumbed-down class named
auto_intto demonstrate just the copy construction functionality without bringing in any complexities introduced by templates or inheritance. I think the code is mostly correct, but it’s untested. Our basicauto_intlook something like this:With this basic
auto_int, we can’t copy a temporary object. Our goal is to be able to write something like:What we can do is use a helper class. For
auto_ptr, this is calledauto_ptr_ref. We’ll call oursauto_int_ref:Basically, an instance of this class just stores a pointer to an
auto_intand allows us to use it as a “reference” to anauto_int.Then in our
auto_intclass we need two additional functions. We need another constructor that takes anauto_int_refand we need a conversion operator that allows anauto_intto be implicitly converted to anauto_int_ref:This will allow us to “copy” a temporary while still having the copy constructor take a non-const reference. If we look again at our sample code:
What happens is we construct a new temporary
auto_intand passnew int()to the constructor that takes anint*. This temporary is then converted to anauto_int_refthat points to it, using theoperator auto_int_ref(), and theauto_intconstructor that takes anauto_int_refis used to initializep.