I've never used auto_ptr, but it looks like all you need to do is return an auto_ptr<Invoice> from the factory::getPtr function instead of a Invoice* to get the functionality your looking for.
@mathhead200:
well there is a problem with the code above. At line 63 the destructor is also called. Hence q seems to be deallocated and at line 65 it seg faults.
thanks
Assuming I have a static pointer called ptr. I think it will be better to make it an autoptr as well like
Your static pointer 'ptr' has no purpose here. You should get rid of it.
The solution is [almost] what Mathhead suggested. Just return an auto_ptr from the function. No need for the factory to keep a copy of that pointer (and in fact, if this is an auto_ptr, it can't keep a copy because auto_ptrs can't be copied).
factory.cpp: In static member function âstatic std::auto_ptr<Invoice> factory::getPtr(int)â:
factory.cpp:46: error: conversion from âderived1*â to non-scalar type âstd::auto_ptr<Invoice>â requested// this is the return new derived1
factory.cpp:50: error: conversion from âderived2*â to non-scalar type âstd::auto_ptr<Invoice>â requested// this is the return new derived2
factory.cpp:53: error: conversion from âintâ to non-scalar type âstd::auto_ptr<Invoice>â requested//this is the return 0
1)And based on what i understood abt auto_ptr is that they can be copied but the copying source will be set to null and the copied destination will have the value.
2)Assuming the client in main() has a Invoice* q(not an auto ptr). Now will this work with the getptr method which return an aurto_ptr. How can this be dealt with, since I cant control how the client will program.
std::auto_ptr's constructor is explicit, try returning std::auto_ptr<Type>(raw_pointer_to_type)
*Edit - and std::auto_ptr<Type>() for a null-auto-ptr
Here's the doc on it http://cplusplus.com/reference/std/memory/auto_ptr/
C++0x adds more features like std::shared_ptr and all its friends from the boost library, so you'll have more flexibility when creating automagically managed systems.
std::auto_ptr<Invoice> factory::getPtr(int type)
{
Invoice* p = 0;
switch(type)
{
case smooth: p = new derived1; break;
case rough: p = new derived2; break;
}
return std::auto_ptr<Invoice>(p);
}
now that works but what if
2)Assuming the client in main() has a Invoice* q(not an auto ptr). Now will this work with the getptr method which return an aurto_ptr. How can this be dealt with, since I cant control how the client will program.
factory.cpp:60: error: cannot convert âstd::auto_ptr<Invoice>â to âInvoice*â in assignment
factory.cpp:61: error: request for member âgetâ in âqâ, which is of non-class type âInvoice*â
*Edit - If I'm understanding your client situation correctly, maybe it would be best for you to make a factory for automatic pointers and one for raw pointers leaving it up to the client to use them properly. You might even be able to use some template specialization to make the package a little prettier for your end-user.
Which means the client should be aware that the code uses an auto_ptr? Cos as i have mentioned a client could just do this by Invoice *ptr without actually a auto_ptr. There is no way arnd this?
The client should definitely be aware that the code uses automatic memory management. The most obvious reason that springs to mind would be the client explicitly calling delete on a "managed" pointer. There might be a way around it, the other members of this site are a whole lot more resourceful than I am when it comes to sneaky C++ magic. :)
If you are returning at auto_ptr, you don't need to do anything, the auto_ptr will clean it up for you. You seem to be confusing how deletion/memory works. In the destructor, you delete memory your CLASS has allocated with new in the constructor; you don't need to worry about the memory your class takes up with automatic variables.
so does that mean that new derived1 and new derived2 will be automatically deallocated. If that is so why does the code calls my destructor. I mean destructor is called to destroy allocated memory for example and if auto_ptr destroys by itself, then seems like i dont need my own destructor.
Or it calls my destructor just in case I have allocated other sort of memory and now need to deallocate it so it calls my own destructor?
so does that mean that new derived1 and new derived2 will be automatically deallocated.
If you are using auto_ptr, yes.
If that is so why does the code calls my destructor. I mean destructor is called to destroy allocated memory for example and if auto_ptr destroys by itself, then seems like i dont need my own destructor.
Your destructor allows your class to clean up any memory your class allocated. This is different from the memory your class occupies as firedraco tried to explain.
If, for instance, you are allocating some memory in Invoice constructor, you would need to free it in your destructor. If you are not doing any memory management in this class, then you probably don't need to write a destructor at all.
Or it calls my destructor just in case I have allocated other sort of memory and now need to deallocate it so it calls my own destructor?
Basically yes.
Here's an example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
class MyClass
{
int* ptr;
public:
MyClass()
{
ptr = newint;
}
};
int main()
{
MyClass* p = new MyClass; // this allocates memory for 'p', then calls the ctor
// the ctor then allocates memory for 'ptr'
delete p; // this deletes the memory for 'p' but DOES NOT delete the memory for 'ptr'
// so we have a memory leak
}
Since 'ptr' is never deleted you have a memory leak. To solve that, you would write a dtor:
class MyClass
{
//...
~MyClass()
{
delete ptr;
}
};
int main()
{
// same as before...
MyClass* p = new MyClass; // this allocates memory for 'p', then calls the ctor
// the ctor then allocates memory for 'ptr'
// now, delete calls p's dtor, which delete's memory for 'ptr'
// then it deletes the memory for 'p'
delete p; // no more memory leaks!
}