Why would a copy constructor have more than one parameter?
$12.8/2 - 'A non-template constructor for class X is a copy constructor if its first parameter is of type X&, const X&开发者_如何学Goamp;, volatile X& or const volatile X&, and either there are no other parameters or else all other parameters have default arguments (8.3.6).106)'
So far, I have not come across any example of a situation where there is a need to declare a copy constructor with additional default parameters.
Would like to know any real time use of such a copy constructor which take more than one parameter.
The old std::basic_string
does have one too:
basic_string(const basic_string& s,
size_type pos = 0, size_type n = npos)
The BDE allocator [PDF Link] used this quirk. For example their array allocator looked like this:
template <typename T>
class bde::Array {
public:
Array(bde::Allocator *allocator = 0);
Array(const Array &rhs, bde::Allocator *allocator = 0);
};
Very cool. Looks like a good way to pass hints to the copy constructor. Some example situations I can think of where this might be useful:
Copying a data structure where the copy will then be populated with additional data
The additional parameter would hint at the likely soon -to-be-needed capacity to optimize allocation. The default capacity would be a sentinel value to indicate just use the default capacity or the capacity of the original data structure.
Whether to do a deep copy or shallow copy of member values
The default might be to do a deep copy for safety, but advanced uses could take advantage of specifying rare occasions of when its safe to do a shallow copy.
Verbatim copy vs logical copy
Hint whether the data structure's copy constructor should copy the original data structure's internal structure verbatim or whether its safe to optimize or consolidate it. For example, the hint could indicate a tree should be balanced as it is copied.
I have a situation where I require the copy constructor to have more than one parameter in one of my class involving deep copy.
Basically the problem is that an object contains another object that need to keep track of it through a pointer, but a normal deep copy would only copy the pointer value and not the correct memory location of the new object.
By disabling the normal copy constructor and using the variant with two parameters I'm able to deep copy correctly my object.
[Edit]: looking through my code it seems that it is even more common than I though as I use it at a couple of place elsewhere too.
Here is a code sample for the curious (this is a simplified version and is actually a little more complicated)
//-----------------------------------------------------------------------------
scan_point::scan_point(scan_point const& rhs, simulation* sim_)
: m(rhs.m), sim(sim_)
//-----------------------------------------------------------------------------
{
}
--
simulation_(simulation_ const& rhs)
{
//...
for(typename ContainerType::const_iterator it = rhs.spContainer->begin(), endIt = rhs.spContainer->end();
it != endIt; it++)
{
spContainer->push_back(new scan_point(*it, this));
}
}
--
To makes things less painful during copy I use smart_ptr class that allow deep copy and (in this case specifically) embed my members in a struct to makes the compiler auto-generate the copying for about all other members (see for a try to a short example: https://stackoverflow.com/questions/469696/what-is-your-most-useful-c-c-utility/1609496#1609496).
精彩评论