C++ -- Is there an implicit cast here from Fred* to auto_ptr<Fred>?
I saw the following code,
#include <new>
#include <memory>
using namespace std;
class Fred; // Forward declaration
typedef auto_ptr<Fred> FredPtr;
class Fred {
public:
static FredPtr create(int i)
{
return new Fred(i); // Is there an implicit casting here? If not, how can we return
// a Fred* with return value as FredPtr?
}
private:
Fred(int i=10) : i_(i) { }
Fred(const Fred& x) : i_(x.i_) { }
int i_;
};
Please see the question listed in function create.
Thank you
开发者_如何学Python// Updated based on comments
Yes, the code cannot pass the VC8.0 error C2664: 'std::auto_ptr<_Ty>::auto_ptr(std::auto_ptr<_Ty> &) throw()' : cannot convert parameter 1 from 'Fred *' to 'std::auto_ptr<_Ty> &'
The code was copied from the C++ FAQ 12.15.
However, after making the following changes,
replace
return new Fred(i);
with
return auto_ptr<Fred>(new Fred(i));
This code can pass the VC8.0 compiler. But I am not sure whether or not this is a correct fix.
std::auto_ptr
does have a constructor that takes a raw pointer as its argument, but that constructor is explicit
and cannot be used as a converting constructor.
This code will not compile.
No, no such implicit conversion exists. It turns out that this is actually a good thing, though. For example, consider this code:
void MyFunction(const std::auto_ptr<Fred>& myFred) {
/* ... do something to Fred. */
}
int main() {
Fred* f = new Fred;
MyFunction(f); // Not legal, but assume it is.
f->doSomething();
}
Here, if you could pass a raw pointer to a Fred into MyFunction, then when that function returned and the temporary auto_ptr object was cleaned up, the memory you allocated in main() would be reclaimed, and the call to f->doSomething() would probably cause a segfault. Making the auto_ptr constructor explicit is a safeguard against this; you don't want to accidentally acquire exclusive ownership of a resource when someone else thinks they already have that access.
The fixed version of the code (return std::auto_ptr<Fred>(new Fred())
) is correct and valid C++. However, I'm not sure what the create()
function buys you in that creating a std::auto_ptr<T>
should be within the skill set of any C++ programmer. Likewise, I'm not clear what typedef
ing std::auto_ptr<Fred>
to FredPtr
buys you, other than a need to look up what a FredPtr
really is.
精彩评论