unique/shared_ptr with custom operator= - c++

I'm working with a polymorphic type (that is, I always interact with it through a pointer) that has methods "Destroy()" and "Clone()", and I would like to wrap it in a resource safe type.
Now, if "Destroy()" was all I had to worry about, then I could use unique_ptr with a custom deleter and it would be easy. But, this resource handle type is used as a member in another type that is otherwise copyable using default generated copy and assign operations. Ideally, I would like to customize the resource handle's copy constructor and assignment to invoke "Clone()", just like I already customize the resource handle's destructor to invoke "Destroy()". But looking through the docs on unique_ptr and shared_ptr, I don't see anything that would let me do that.
Did I miss something in the docs? Is there a ready-made std way to do this?
If not, should I extend unique_ptr and override the copy operations?
Alternatively, should I just write my own resource handle with all the usual pointer semantics from scratch?

You may create wrapper around std::unique_ptr
// To handle your cusstom Destroy
struct DestroyDeleter
{
void operator(Interface* o) {
object->Destroy();
delete object;
}
};
using InterfacePtr = std::unique_ptr<Interface, DestroyDeleter>;
// To handle the copy with clone:
class wrapper
{
public:
explicit wrapper(InterfacePtr o) : data(std::move(o)) {}
wrapper(const wrapper& rhs) : data(rhs.data->Clone()) {}
wrapper(wrapper&& rhs) = default;
wrapper& operator =(const wrapper& rhs) { data = rhs.data->Clone(); }
wrapper& operator =(wrapper&& rhs) = default;
const Interface* operator ->() const { return data.get(); }
Interface* operator ->() { return data.get(); }
const Interface& operator *() const { return data; }
Interface& operator *() { return *data; }
private:
InterfacePtr data;
};

One of the reasons for having a unique_ptr and a shared_ptr is that copying and juggling these pointers around is a cheap operation that does not involve copying the underlying object.
And that's why smart pointers do not implement any means for you to install your own operator=. As I understand your question, you want to wedge in a call to your custom Clone() and Destroy() methods, when a smart pointer gets copied.
Well, unique_ptr and shared_ptr implement their own operator= that does the right thing.
For starters whatever is being done by your Destroy() should really be done in your class's destructor. That's what a destructor is for. Then, your clone() method simply needs to clone its own object, and return a new unique_ptr, so, when you already have an existing unique_ptr or a shared_ptr, using it to invoke the clone() method clones the object and returns a smart pointer to the cloned object:
std::unique_ptr<myClass> p; // Or std::shared_ptr
// p is initialized, populated from there.
std::unique_ptr<myClass> new_p=p->clone();
Having a distinct Destroy() method that must be invoked before destroying an object is an invitation to spawn an endless parade of bugs. It's only a matter of time before you forget to call it when destroying a cloned object.
The best way to avoid creating and wasting time with bugs in your code is to make it logically impossible for them to happen. If something needs to be done in order to destroy an object, this needs to be done in the destructor. If something extra needs to be done in order to destroy an object that was cloned from another object, the object needs to have an internal flag that indicates that it's a cloned object, and have its destructor do the right thing, based on that.
Once that's done, it will become logically impossible for your code to screw up, by forgetting to do something to get rid of a cloned object. You can congratulate yourself for saving yourself, in the future, from wasting time searching for a bunch of bugs that will never be created, now. Your future self will thank your past self. Just use smart pointers as they were intended to be used, and have clone() give you a smart pointer right from the start.

Related

Overloading operator= of user defined type with unique_ptr data member

I have a user defined class that has a std::unique_ptr member. I am trying to overload the assignment operator to new an object of the same type to the unique_ptr member or assign the value to the ptr value.
class object
{
public:
// POD types
object& operator=(const object& _obj);
std::unique_ptr<baseClass> ptr;
}
I've tried using:
std::unique_ptr::swap()
but the swap function is non-const so I attempted assigning the the result of:
std::unique_ptr::get()
to the ptr and then calling:
std::unique_ptr::release()
but release also is non const, so I cannot guarantee that ptr will be destructed correctly since the old ptr will still have ownership. Alas, operator=() for unique_ptr does not accept a non-const reference to another unique_ptr so I have opted to make the operator= as so for my class.
object& object::operator=(const object& _obj)
{
//POD types use operator= as normal
ptr.reset(nullptr);
return *this;
}
And just call a setPtr() method later on to set the ptr. I wanted to just detect the type and just assign the ptr using:
ptr.reset(new detectedType );
but the consensus all over Stack Overflow and my preferred search engine is that detecting types like this would be a design flaw. My question is: am I overlooking something simple and is there a better way to overload the assignment operator for user defined types that have a unique_ptr member?
Before post edit:
I changed the parameter to object& rather than const object& and it worked. Is this a good way to correct this issue or should I be trying to work with only const references to the other class?
My question is: am I overlooking something simple and is there a better way to overload the assignment operator for user defined types that have a unique_ptr member?
There is indeed. This breaks down to understanding what smart pointers in C++ do. Usually you use a std::unique_ptr if there will be one and only one reference to your object. This is the reason why std_unique_ptrs are neither copy-constructable nor copy-assignable. If you manually create two copies of a std::unique_ptr as you describe in you post by using ptr.get() you will end up in an invalid state, because as soon as one copy leaves scope, the std::unique_ptr destructor will also destruct the object it points to, leaving the other std::unqiue_ptr in an invalid state (it points to a freed memory location). So if there might be several references to your object you should probably use std::shared_ptr instead.
In your examples the question is what do you want to achieve?
If you want your assignment operator such that after calling a = b, a.ptr and b.ptr point to the exact same object (i.e. store the same pointer) use a shared pointer. You should definitely NOT use a unique pointer in this case, as calling the destructor for a or b would destruct the object pointed to, leaving a or b in an invalid state.
If you want that after calling a = b, a.ptr points to independent copy of *(b.ptr) you can indeed use a unique pointer and implement you assignment operator like this (provided baseClass is copy construable) :
object& object::operator=(const object& _obj)
{
//POD types use operator= as normal
ptr.reset(new baseClass(*_obj.ptr));
return *this;
}
Note however that this only works if baseClass is final (unlikely considering the name...), i.e. ptr won't store pointers to objects of a derived class. Otherwise this results in slicing as pointed out by BenVoigt.
Finally, it is generally expected that calling a = b does not change b. Therefore making the ptr member mutable and using swap sounds like a bad idea to me. If you want to achieve this behavior because of performance (or other) considerations, I would suggest to implement the move assignment operator instead
object& object::operator=(object&& _obj)
{
//POD types use operator= as normal
ptr = std::move(_obj.ptr);
return *this;
}
and call a = std::move(b), which makes clear that b might end up in a different state.
This is a good use case for the mutable keyword. If you declare ptr as mutable, you are indicating that even when an instance of your class is semantically const, it must perform non-const operations on a particular data member. Declare your class as follows, and you should be able to implement your original idea of using swap:
class object
{
public:
// POD types
object& operator=(const object& _obj);
mutable std::unique_ptr<baseClass> ptr;
}

How to use shared_ptr to manage already ref-count managed objects?

if an object is already reference-counted (like glib in C), having obj_ref, obj_unref. All we have is a pointer like obj *p.
How can we use c++'s shared_ptr to manage the object so that we can have an uniform interface.
Ok, it seems that a lot of people have misunderstood my intension.
The greatest issue here is not about deleter. It's about inform of the original manager that I increased the refcount.
If I assigned or copied, only std::shared_ptr increased the refcount, but the original one did not. Is there anyway to inform it? So as the unref operation.
std::shared_ptr allows you to pass a custom deleter which is called when the owned object should be destroyed. You could use it to call obj_unref.
obj* p = create_obj();
p->obj_ref();
std::shared_ptr<obj> sp(p, [](auto p) {
p->obj_unref();
});
/* use sp normally, obj will be 'obj_unref'ed and deleted when sp goes out of scope */
I don't know how a obj is created and if it gets destroyed by obj_unref() when the count reaches 0, but I hope you see what I mean.
The idea is to increment objs internal reference count just once at the beginning, and decrement it just once when the last shared_ptr is destroyed.
Don't try to somehow duct tape std::shared_ptr's refcounting to your custom one, that won't end well. Just write a custom pointer:
struct objPtr {
objPtr()
: _ptr{nullptr} { }
objPtr(obj *ptr)
: _ptr{ptr} {
if(_ptr)
_ptr->obj_ref();
}
~objPtr() {
if(_ptr)
_ptr->obj_unref();
}
objPtr(objPtr const &orig)
: objPtr{orig._ptr} { }
objPtr &operator = (objPtr const &orig) {
obj *const oPtr = std::exchange(_ptr, orig._ptr);
_ptr->obj_ref();
oPtr->obj_unref();
return *this;
}
obj &operator * () { return *_ptr; }
obj const &operator * () const { return *_ptr; }
obj *operator -> () { return _ptr; }
obj const *operator -> () const { return _ptr; }
operator bool() const { return _ptr; }
bool operator ! () const { return !_ptr; }
private:
obj *_ptr;
};
Add move construction and assignment if you so wish.
When you want a shared_ptr, start with a unique_ptr. Then build up.
struct cleanup_obj {
// not called with nullptr:
void operator()(obj* t)const {
obj_unref(t);
}
};
using obj_unique_ptr = std::unique_ptr<T, cleanup_obj>;
using obj_shared_ptr = std::shared_ptr<T>;
template<class T>
obj_unique_ptr<T> make_unique_refcount( T* t ) {
using ptr=obj_unique_ptr<T>;
if (!t) return ptr();
obj_ref(t);
return ptr(t);
}
template<class T>
obj_shared_ptr<T> make_shared_refcount( T* t ) {
return make_unique_refcount(t); // implicit convert does right thing
}
What did I do?
First, I wrote a unique_ptr wrapper, because we may as well be complete, and it solves the shared_ptr case via the unique_ptr->shared_ptr implicit conversion.
For unique_ptr, we have to say we aren't using the default object destroyer. In this case, we are using a stateless function object that knows how to obj_unref an obj*. The stateless function object keeps the overhead at zero.
For the null case, we don't first add a reference, as that is rude.
For shared_ptr, the fact that we have a working unique_ptr makes it a free function. shared_ptr will happily store the destroyer function that unique_ptr has. It doesn't have to be told it has a special object destroyer, because shared_ptr type erases object destruction by default. (This is because unique_ptr<T> is zero-overhead over a naked pointer, while shared_ptr<T> has unavoidable overhead of the reference counting block; the designers figured once you have that reference counting block, adding in a type-erased destruction function was not really expensive).
Note that our obj_unique_ptr<T> is also zero overhead over a naked pointer. Quite often you'll want one of these instead of the shared one.
Now, you can upgrade the obj_unique_ptr to a full on intrusive pointer, with less overhead than a shared_ptr, if you want.
template<class T>
struct obj_refcount_ptr : obj_unique_ptr<T> // public
{
// from unique ptr:
obj_refcount_ptr(obj_unique_ptr<T> p):obj_unique_ptr<T>(std::move(p)){}
obj_refcount_ptr& operator=(obj_unique_ptr<T> p){
static_cast<obj_unique_ptr<T>&>(*this)=std::move(p);
return *this;
}
obj_refcount_ptr(obj_refcount_ptr&&)=default;
obj_refcount_ptr& operator=(obj_refcount_ptr&&)=default;
obj_refcount_ptr()=default;
obj_refcount_ptr(obj_refcount_ptr const& o):
obj_refcount_ptr(make_unique_refcount(o.get())
{}
obj_refcount_ptr& operator=(obj_refcount_ptr const& o) {
*this = make_unique_refcount(o.get());
return *this;
}
};
which I think covers it. Now it is a zero-overhead reference counting intrusive smart pointer. These intrusive smart pointers can be converted toa std::shared_ptr<T> via implicit conversion, as they are still unique_ptrs. They are just unique_ptrs we have taught to copy themselves!
It does require moving from an obj_refcount_ptr to get a shared_ptr. We can fix this:
operator std::shared_ptr<T>() const {
return obj_refcount_ptr(*this);
}
which creatres an obj_refcount_ptr copy of *this and moves it into the shared_ptr. Only one add ref is called, and the remove ref is only called when the shared_ptr count goes to zero.
The general approach is to start with the simplest smart pointer (unique_ptr), get it right, then exploit its implementation to get us the shared_ptr and eventually the refcount_ptr. We can test the unique_ptr implementation in isolation, and its correctness makes testing the richer pointers easier.
The most simplest approach, the least invasive one with the minimal possibility of breaking something, is to simply write your own facade for the object, with the underlying object as a private member and providing simple wrappers to access it.
Then use a std::shared_ptr to that.
It's an incredibly bad idea to have the same objects in multiple smart pointer implementations as their ref counts can't know about each other. As soon as the ref count hits zero in one it will delete the object even if the other still holds refs.
If you really had to you could construct your smart pointers with custom deleters (that do nothing), but I really wouldn't recommend this approach.
Pick one implementation and stick to it.

How to write handles for classes that don't have clone() member?

I'm following an example in Accelerated C++ and writing a simple Handle class that will act as a smart pointer. This uses the virtual ctor idiom using a virtual clone() function. So far so good. But what to do when I want to use my Handle for classes that I don't control that don't provide clone()?
The method suggested in the book is to create a global clone function and use template specialization (something I'm seeing for the first time) so that if clone() is called with a particular argument, one can write code to handle that case.
My question is: This means that I have to write a clone() version for every type of class that I envision my user can use Handle with. This seems quite hard! Is there a more elegant and/or simple way to solve this issue? How is it possible that things like auto_ptr or boost::shared_ptr are able to provide this functionality without the tedious clone() definitions?
For completeness, here's my Handle class implementation:
template <class T> class Handle
{
public:
Handle() : p(0) {}
Handle(T* t) : p(t) {}
Handle( const Handle& s ) :p(0) { if (s.p) p = s.p->clone(); }
const Handle& operator=( const Handle& );
~Handle() { delete p; }
operator bool() { return p; }
T& operator*() { if (p) return *p; else throw std::runtime_error("Handle not bound"); }
T* operator->() { if (p) return p; else throw std::runtime_error("Handle not bound"); }
private:
T* p;
};
Thanks!
The solution to this problem is to simply not write Handles for these kinds of classes. No. Really.
auto_ptr (deprecated as of C++11) never needs to clone the underlying object, because auto_ptr never copies the object. An auto_ptr only ever has one copy of the object, and when the auto_ptr is copied, control of the object is transfered -- that object is not copied.
unique_ptr never needs to clone the underlying object, because there is only ever one unique_ptr that owns the object. unique_ptr is noncopyable, and is only movable.
shared_ptr never needs to clone because it also only ever controls one copy of the object. Copying the shared_ptr only increments the reference count, and that single object is destroyed when the reference count is zero.
In general, if there's no way to deep copy the resource your class is controlling, then you should just make the class noncopyable. If clients need to pass references to your class around, they can place the class in an auto_ptr, unique_ptr, or shared_ptr themselves.

How do use a std::auto_ptr in a class you have to copy construct?

I have class foo that contains a std::auto_ptr member that I would like to copy construct but this does not appear to be allowed. There's a similar thing for the assignment. See the following example:
struct foo
{
private:
int _a;
std::string _b;
std::auto_ptr< bar > _c;
public:
foo(const foo& rhs)
: _a(rhs._a)
, _b(rhs._b)
, _c(rhs._c)
// error: Cannot mutate rhs._c to give up ownership - D'Oh!
{
}
foo& operator=(const foo& rhs)
{
_a = rhs._a;
_b = rhs._b;
_c = rhs._c;
// error: Same problem again.
}
};
I could just declare _c as mutable but I'm not sure this is correct. Does anyone have a better solution?
EDIT
OK, I'm not getting the kind of answer that I was expecting so I'll be a little more specific about the problem.
An object of type foo is created on the stack and passed by value into a container class (not stl) and then goes out of scope. I don't have any control over the container code. (It's actually an active queue implementation, with bugs.)
The bar class is a fairly heavyweight parser. It has very poor performance on new and delete so even if it was copy constructable, it would be way too expensive.
We can guarantee that when a bar object is created, it will only ever need to be owned in 1 place at a time. In this case it is being passed between threads and deleted when the transaction is completed. This is why I was hoping to use a std::autp_ptr.
I am very willing to consider boost smart pointers but I was hoping to guarantee this uniqueness if there is an alternative.
You might want to try following code:
foo(const foo& rhs)
: _a(rhs._a)
, _b(rhs._b)
, _c(_rhs._c.get() ? new bar(*_rhs._c.get()) : 0)
{
}
(Assignment operator is similar.)
However this will only work if bar is CopyConstructible and if this indeed does what you want. The thing is that both foo objects (_rhs and constructed one) will have different pointers in _c.
If you want them to share the pointer then you must not use auto_ptr as it does not support shared ownership. Consider in such case use of shared_ptr from Boost.SmartPtr for example (which will be included in new C++ standard). Or any other shared pointer implementation as this is such a common concept that lots of implementations are available.
As you have discovered you can't copy a std::auto_ptr like that. After the copy who owns the object pointed to? Instead you should use a reference counted smart pointer. The Boost library has a shared_ptr you could use.
First, I'd avoid auto_ptr
Transfer of ownership is good in some scenarios, but I find they are rare, and "full fledged" smart pointer libraries are now available easily. (IIRC auto_ptr was a compromise to include at least one example in the standard library, without the delays that a good implementation would have required).
See, for example here
or here
Decide on semantics
Should the copy of foo hold a reference to the same instance of bar? In that case, use boost::shared_ptr or (boost::intrusive_ptr), or a similar library.
Or should a deep copy be created?
(That may sometimes be required, e.g. when having delay-created state). I don't know any standard implementation of that concept, but it's not to complex to build that similar to existing smart pointers.
// roughly, incomplete, probably broken:
template <typename T>
class deep_copy_ptr
{
T * p;
public:
deep_copy_ptr() : p(0) {}
deep_copy_ptr(T * p_) : p(p_) {}
deep_copy_ptr(deep_copy_ptr<T> const & rhs)
{
p = rhs.p ? new T(*rhs.p) : 0;
}
deep_copy_ptr<T> & operator=(deep_copy_ptr<T> const & rhs)
{
if (p != rhs.p)
{
deep_copy_ptr<T> copy(rhs);
swap(copy);
}
}
// ...
}
The std::auto_ptr is a good tool for managing dynamic object in C++ but in order to use it effectivelly it's important to unserstand how auto_ptr works. This article explains why, when and where this smart pointer should be used.
In your case, first of all your should decide what you want to do with the object inside your auto_ptr. Should it be cloned or shared?
If it should be cloned, make sure it has a copy constructor and then your create a new auto_ptr which contains a copy of your the object see Adam Badura's answer.
If it should shared, you should use boost::shared_ptr as Martin Liversage suggested.
If I have class containing an auto_ptr, and want deep-copy semantics, I generatally only do this for classes that have a virtual copy operator, i.e. clone().
Then, within the copy constructor, I initialize the auto_ptr to a clone() of the other; e.g.
class Foo
{
public:
Foo(const Foo& rhs) : m_ptr(rhs.m_ptr->clone());
private:
std::auto_ptr<T> m_ptr;
};
clone() is typically implemented as follows:
class T
{
std::auto_ptr<T> clone() const
{
return std::auto_ptr<T>(new T(*this));
}
};
We are imposing the condition that T is clonable, but this condition is essentially imposed by having a copiable class with an auto_ptr member.
The whole idea of the auto_ptr is that there's only one owner of the referred to object. This implies you cannot copy the pointer without removing the original ownership.
Since you cannot copy it, you also can't copy an object containing an auto_ptr.
You might try to use move-semantics by e.g. using std::swap instead of copy.
My first choice would be to avoid auto_ptr in this situation altogether. But if I were backed against a wall, I might try to use the keyword mutable in the declaration of _c - this will allow it to be modified even from a const reference.
Given the edit, then it appears you want tranfer of ownership semantics.
In that case, then you'll want to have your copy constructor and assignment operator accept non-const references to their arguments, and perform the initialization/assignment there.
You can't use const references in a copy constructor or assignment operator that involves an auto_ptr<>. Remove the const. In other words, use declarations like
foo(foo & rhs);
foo & operator=(foo & rhs);
These forms are explicitly mentioned in the Standard, primarily in section 12.8. They should be usable in any standard-conforming implementation. In fact, paragraphs 5 and 10 of 12.8 says that the implicitly defined copy constructor and assignment operator (respectively) will take a non-const reference if any of the members require it.

auto_ptr question in c++

I am new here.
I am also new on C++
So here is the class and function i wrote.But i got the compiler error
My class:
class fooPlayer
{
public:
void fooPlayerfunc(){}//doing something here
char askYesNo(std::string question);
};
class fooPlayerFactory
{
public:
virtual std::auto_ptr<fooPlayer> MakePlayerX() const;
virtual std::auto_ptr<fooPlayer> MakePlayerO() const;
private:
std::auto_ptr<fooPlayer> MakePlayer(char letter) const;
std::auto_ptr<fooPlayer> my_player;
};
Implement my class:
auto_ptr<fooPlayer> fooPlayerFactory:: MakePlayer(char letter) const
{
my_player->fooPlayerfunc();
return my_player;
}
auto_ptr<fooPlayer> fooPlayerFactory::MakePlayerX() const
{
char go_first = my_player->askYesNo("Do you require the first move?");
MakePlayer(go_first);
return my_player;
}
auto_ptr<fooPlayer> fooPlayerFactory::MakePlayerO() const
{
return my_player;
}
My main() function here:
int main()
{
fooPlayerFactory factory;
factory.MakePlayerX();
factory.MakePlayerO();
}
I got the error:
error C2558: class 'std::auto_ptr<_Ty>' : no copy constructor available or copy constructor is declared 'explicit'
I do not know how to change it even after reading the document on this link:
The reason for the error is that you are calling the copy constructor of auto_ptr my_player in fooPlayerFactory::MakePlayerO() which is a const method. That means that is cannot modify its members.
However the copy constructor of auto_ptr DOES modify the right hand side so returning my_player trys to change its pointer to 0 (NULL), while assigning the original pointer to the auto_ptr in the return value.
The signature of the copy constuctor is
auto_ptr<T>::auto_ptr<T>(auto_ptr<T> & rhs)
not
auto_ptr<T>::auto_ptr<T>(const auto_ptr<T> & rhs)
The copy constructor of auto_ptr assigns ownership of the pointer to the left hand side, the right hand side then holds nothing.
I don't think you want to use auto_ptr here, you probably want boost::smart_ptr
It looks like you have mixed up two uses for auto_ptr
The first is as poor man's boost::scoped_ptr. This is to manage a single instance of a pointer in a class, the class manages the life time of the pointer. In this case you don't normally return this pointer outside your class (you can it is legal, but boost::smart_ptr / boost::weak_ptr would be better so clients can participate the life time of the pointer)
The second is its main purpose which is to return a newly created pointer to the caller of a function in an exception safe way.
eg
auto_ptr<T> foo() {
return new T;
}
void bar() {
auto_ptr<T> t = foo();
}
As I said I think you have mixed these two uses auto_ptr is a subtle beast you should read the auto_ptr docs carefully. It is also covered very well in Effective STL by Scott Meyers.
In your code:
auto_ptr<fooPlayer> fooPlayerFactory:: MakePlayer(char letter) const
{
my_player->fooPlayerfunc();
return my_player;
}
This is a const function, but fooPlayerfunc is not const - my compiler reports this error rather than the one you say you are getting. Are you posting the real code?
I don't think you actually want to constructing dynamic objects here.
A factory object creates and returns an object it normally does not keep a reference to it after creation (unless you are sharing it), and I don't actually see anywhere that you are creating the player.
If you only ever create one player internally in your (fooPlayerFactory). Then create an object and return references to it.
Edit: in response to the comment (which is correct, my bad), I left only the advice part.
Best practice is to have the factory methods just return a plain old pointer to the underlying object, and let the caller decide how to manage ownership (auto_ptr, scoped_ptr, or whatever).
Also your code is buggy, any class that implements virtual methods should have a virtual destructor.
I'm not seeing anywhere you construct my_player, so I have a feeling that some of the code is missing. Specifically, I think your constructor has this line:
my_player = new fooPlayer()
A fooPlayer object is not quite the same thing as an auto_ptr<fooPlayer> object, and auto_ptr is intentionally designed to prevent assigning from one to the other because, frankly, the alternative is worse. For the details, look up (1) conversion constructors, (2) the explicit keyword, and (3) copy constructors and destructive copy semantics.
You should change the constructor to either:
class fooPlayerFactory {
public:
fooPlayerFactory()
{
my_player = std::auto_ptr<fooPlayer>(new fooPlayer());
}
Or (using a member initializer list):
class fooPlayerFactory {
public:
fooPlayerFactory() : my_player(std::auto_ptr<fooPlayer>(new fooPlayer()) { }
The solution isn't pretty but, like I said, the alternative is worse due to some really arcane details.
As a bit of advice, though, you're making life harder than it needs to be; and may in fact be causing strange bugs. auto_ptr exists to manage the lifetime of an object, but the only reason you need to worry about the lifetime of my_player is that you've allocated it with new. But there's no need to call new, and in fact there's no need to keep my_player. And unless fooPlayerFactory is meant to be the base class for some other factory, there's no need to mark functions virtual.
Originally I thought you could get away with simply returning copies of the my_player object, but there's a problem: before returning my_player from MakePlayer() you call a method on it, and I assume that method changes the internal state of my_player. Further calls to MakePlayer() will change the state again, and I think you're going to eventually have my_player in the wrong state. Instead, return a different fooPlayer object with each request. Don't do memory management, just promise to construct the object. That way the user can decide on memory allocation:
fooPlayerFaclotry factory;
fooPlayer on_stack = factory.MakePlayerX();
fooPlayer* on_heap_raw_pointer = new fooPlayer(factory.MakePlayerO());
std::auto_ptr<fooPlayer> on_heap_managed_scope
= std::auto_ptr<fooPlayer>(factory.MakePlayerX());
I would change fooPlayerFactory to look like this:
class fooPlayerFactory
{
private:
fooPlayer MakePlayer(const char letter) const
{
fooPlayer result;
result.fooPlayerfunc();
return result;
}
public:
fooPlayer* MakePlayerX() const
{
char go_first = askYesNo("Do you require the first move?");
return MakePlayer(go_first);
}
fooPlayer MakePlayerO() const
{
return fooPlayer();
}
};