Default Initialize or Check For Null - c++

I'd like to know is it better to specify a default initialization for a smart-pointer or do a NULL value check before accessing the smart-pointers methods?
Currently I've been using the method below to avoid calling increment() on a NULL pointer. Is this a reasonable way of doing things or is there a pitfall that I don't see?
Note: We use a custom smart-pointer class and I don't have the Boost libraries on my current configuration to test compile this code. This should compile, but YMMV.
Example.h
#include <boost/shared_ptr.hpp>
class Foo
{
public:
Foo() : mFoo(0) {}
Foo(int rawValue) : mFoo(rawValue) {}
void increment() { mFoo++; }
private:
int mFoo;
};
typedef boost::shared_ptr<Foo> FooSP;
class MyClass
{
public:
MyClass() : mFoo(new Foo()) {}
FooSP foo() { return mFoo; }
void setFoo(FooSP newFoo) { mFoo = newFoo; }
private:
FooSP mFoo;
};
Main.cpp
#include <Example.h>
int main()
{
MyClass temp; // Default-constructed
temp.foo()->increment(); // Increment Foo's member integer
// Before: mFoo = 0
// After: mFoo = 1
FooSP tempFoo = new Foo(10); // Create a Foo with a default size
temp.setFoo(FooSP(new Foo(10))); // Explicitly set the FooSP member
temp.foo()->increment(); // Increment the new FooSP
// Before: mFoo = 10
// After: mFoo = 11
return 0;
}

If you are using a smart pointer as a general replacement for a pointer type, you cannot get away from a check for null. This is because a class defined with a smart pointer with a default constructor is likely to allow the smart pointer to be created with its default constructor. Dynamically creating a new object just to fill the pointer until you can set it seems to be a waste of resources.
shared_ptr's constructor is explicit, so your initialization of tempFoo won't compile. If you wanted to save a line of code, you can avoid declaring the temporary like this:
temp.setFoo(FooSP(new Foo(10)));
You can also declare the method of setFoo to take a constant reference, to avoid manipulating the reference count when taking in the parameter.
void setFoo(const FooSP &newFoo) { mFoo = newFoo; }
Or use swap on the parameter instance.
void setFoo(FooSP newFoo) { std::swap(mFoo, newFoo); }
If I were required to implement something along the lines of what you are proposing, I would create a static instance of Foo to serve as the null version, and then have the increment method throw an exception if it was the null version.
class Foo
{
public:
static Foo Null;
//...
void increment() {
if (this == &Null) throw Null;
mFoo++;
}
//...
};
struct DeleteFoo {
void operator () (Foo *t) const {
if (t != &Foo::Null) delete t;
}
};
class MyClass
{
public:
MyClass() : mFoo(&Foo::Null, DeleteFoo()) {}
//...
};
Note the custom deleter for FooSP to properly deal with Foo::Null.

is it better to specify a default initialization for a smart-pointer or do a NULL value check before accessing the smart-pointers methods?
There is no right answer which applies to every case (more soon). If I had to err to one or the other, I would err toward NULL testing without default initialization because that's an obvious programmer error which can be detected and corrected easily.
However, I think the right answer is that there are good reasons we use multiple idioms for construction and initialization, and that you should choose the best approach for your program.
Typically, I will be explicit (no default or no default initialization) in the lower level classes, as well as complex higher level classes. When the classes are mid-level and defaults and ownership are more obvious (often because of limited use cases), then a default may be sensible.
Often, you will just want to be consistent, to avoid surprising clients. You'll also need to be aware of the complexity of allocating default-initialized objects. If it's big and complex to create, and a default does not make sense, then you are simply wasting a lot of resources when the default-constructed object is the wrong choice.
a) do not apply a default where it does not make sense. the default should be obvious.
b) avoid wasted allocations.
In addition to the approaches you have mentioned, there are a few other angles you might also consider:
Matching Foo's declared constructors in MyClass. At least, the ones which pertain to MyClass.
If copyable and efficient to copy, passing a Foo to MyClass's constructor.
Passing Foo in a container (smart pointer in this case) to MyClass's constructor to remove any ambiguity and to offer the client the option to construct (and share, in the case of a shared pointer) Foo as they desire.
Is this a reasonable way of doing things or is there a pitfall that I don't see?
Wasted allocations. Surprising results. It can restrict capabilities. The most obvious, broadly applicable problems are time and resource consumption.
To illustrate some scenarios:
say Foo reads a 1MB file every time it is constructed. when construction parameters are necessary and the default is not the right option, the file would have to be read a second time. the innocent default would double the disk io required.
in another case, an omitted construction parameter may be another large or complex shared pointer. if absent, Foo may create its own -- when the resource could/should have been shared.
Constructors parameters are often very important, and often should not be erased from the interface. It's certainly fine to do so in some cases, but these conveniences can introduce a lot of restrictions or introduce much unnecessary allocations and CPU time as the contained object's complexity increases.
Using both approaches in your programs is fine. Using additional approaches I outlined is also fine. Specifically, using the right approach for the problem is ideal - there are multiple ways to implement ideal solutions available; you just have to determine what that is in the context of what it is your program is trying to do. All these approaches have separate pros and cons - there is often an ideal match for the context of your program's operation and exposed interfaces.

Related

C++ force dynamic allocation with unique_ptr?

I've found out that unique_ptr can point to an already existing object.
For example, I can do this :
class Foo {
public:
Foo(int nb) : nb_(nb) {}
private:
int nb_;
};
int main() {
Foo f1(2);
Foo* ptr1(&f1);
unique_ptr<Foo> s_ptr1(&f1);
return 0;
}
My question is :
If I create a class with unique_ptr< Bar > as data members (where Bar is a class where the copy constructor was deleted) and a constructor that takes pointers as argument, can I prevent the user from passing an already existing object/variable as an argument (in that constructor) (i.e. force him to use the new keyword) ?
Because if he does, I won't be able to guarantee a valide state of my class objects (the user could still modify data members with their address from outside of the class) .. and I can't copy the content of Bar to another memory area.
Example :
class Bar {
public:
Bar(/* arguments */) { /* data members allocation */ }
Bar(Bar const& b) = delete;
/* Other member functions */
private:
/* data members */
};
class Bar_Ptr {
public:
Bar_Ptr(Bar* ptr) {
if (ptr != nullptr) { ptr_ = unique_ptr<Bar> (ptr); }
} /* The user can still pass the address of an already existing Bar ... */
/* Other member functions */
private:
unique_ptr<Bar> ptr_;
};
You can't prevent programmers from doing stupid things. Both std::unique_ptr and std::shared_ptr contain the option to create an instance with an existing ptr. I've even seen cases where a custom deleter is passed in order to prevent deletion. (Shared ptr is more elegant for those cases)
So if you have a pointer, you have to know the ownership of it. This is why I prefer to use std::unique_ptr, std::shared_ptr and std::weak_ptr for the 'owning' pointers, while the raw pointers represent non-owning pointers. If you propagate this to the location where the object is created, most static analyzers can tell you that you have made a mistake.
Therefore, I would rewrite the class Bar_ptr to something like:
class Bar_ptr {
public:
explicit Bar_ptr(std::unique_ptr<Bar> &&bar)
: ptr(std::move(bar)) {}
// ...
}
With this, the API of your class enforces the ownership transfer and it is up to the caller to provide a valid unique_ptr. In other words, you shouldn't worry about passing a pointer which isn't allocated.
No one prevents the caller from writing:
Bar bar{};
Bar_ptr barPtr{std::unique_ptr<Bar>{&bar}};
Though if you have a decent static analyzer or even just a code review I would expect this code from being rejected.
No you can't. You can't stop people from doing stupid stuff. Declare a templated function that returns a new object based on the templated parameter.
I've seen something similar before.
The trick is that you create a function (let's call it make_unique) that takes the object (not pointer, the object, so maybe with an implicit constructor, it can "take" the class constructor arguments) and this function will create and return the unique_ptr. Something like this:
template <class T> std::unique_ptr<T> make_unique(T b);
By the way, you can recommend people to use this function, but no one will force them doing what you recommend...
You cannot stop people from doing the wrong thing. But you can encourage them to do the right thing. Or at least, if they do the wrong thing, make it more obvious.
For example, with Bar, don't let the constructor take naked pointers. Make it take unique_ptrs, either by value or by &&. That way, you force the caller to create those unique_ptrs. You're just moving them into your member variables.
That way, if the caller does the wrong thing, the error is in the caller's code, not yours.

Pros and Cons of usage of reference in case of PIMPL idiom

As mentioned here you can use reference (d-reference) instead of pointer (d-pointer) in case of PIMPL idiom.
I'm trying to understand if there are any serious issues with this implementation and what are the pros and cons.
Pros:
Shorter syntax because of usage of "." instead of "->".
...
Cons:
What if the new ObjectPivate() fails and new doesn't throw (e.g.: new(std::nothrow) or custom new) and returns nullptr instead? You need to implement additional stuff to check if the referance is valid. In case of pointer you just use:
if (m_Private)
m_Private->Foo();
In rare case of multiple constructors for the Object with complex initialisation logic the solution could be not applicable. [© JamesKanze]
It fills more natural to use pointer for memory management. [© JamesKanze]
Some additional implementation details needs to be considered (use of swap()) to ensure the exception-safety (e.g. implementation of assignment operator) [© Matt Yang]
...
Here the sample code for illustration:
// Header file
class ObjectPrivate;
class Object
{
public:
Object();
virtual ~Object();
virtual void Foo();
private:
ObjectPrivate& m_Private;
};
// Cpp file
class ObjectPrivate
{
public:
void Boo() { std::cout << "boo" << std::endl; }
};
Object::Object() :
m_Private(* new ObjectPrivate())
{
}
Object::~Object()
{
delete &m_Private;
}
void Object::Foo()
{
m_Private.Boo();
}
It's really just a matter of style. I tend to not use
references in classes to begin with, so using a pointer in the
compilation firewall just seems more natural. But there's
usually no real advantage one way or the other: the new can
only fail by means of an exception.
The one case where you might favor the pointer is when the
object has a lot of different constructors, some of which need
preliminary calculations before calling the new. In this
case, you can initialize the pointer with NULL, and then call
a common initialization routine. I think such cases are rare,
however. (I've encountered it once, that I can recall.)
EDIT:
Just another style consideration: a lot of people don't like something like delete &something;, which is needed if you use references rather than pointers. Again, it just seems more natural (to me, at least), that objects managing memory use pointers.
It's not convenient to write exception-safe code I think.
The first version of Object::operator=(Object const&) might be:
Object& operator=(Object const& other)
{
ObjectPrivate *p = &m_Private;
m_Private = other.m_Private; // Dangerous sometimes
delete *p;
}
It's dangerous if ObjectPrivate::operator=(ObjectPrivate const&) throws exception. Then what about using a temporary variable? Aha, no way. operator=() has to be invoked if you want change m_Private.
So, void ObjectPrivate::swap(ObjectPrivate&) noexcept can act as our savior.
Object& operator=(Object const& other)
{
ObjectPrivate *tmp = new ObjectPrivate(other.m_Private);
m_Private.swap(*tmp); // Well, no exception.
delete tmp;
}
Then consider the implementation of void ObjectPrivate::swap(ObjectPrivate&) noexcept. Let's assume that ObjectPrivate might contain a class instance without swap() noexcept or operator=() noexcept. I think it's hard.
Alright then, this assumption is too strict and not correct sometimes. Even so, it's not necessary for ObjectPrivate to provide swap() noexcept in most cases, because it's usually a helper structure to centralize data.
By contrast, pointer can save a lot of brain cells.
Object& operator=(Object const& other)
{
ObjectPrivate *tmp = new ObjectPrivate(*other.p_Private);
delete p_Private;
p_Private = tmp; // noexcept ensured
}
It's much more elegant if smart pointers are used.
Object& operator=(Object const& other)
{
p_Private.reset(new ObjectPrivate(*other.p_Private));
}
Some quick and obvious additions:
Pro
The reference must not be 0.
The reference may not be assigned another instance.
Class responsibilities/implementation are simpler due to fewer variables.
The compiler could make some optimizations.
Con
The reference may not be assigned another instance.
The reference will be too restrictive for some cases.

Return value copying issue (to improve debug timing) -- What's the solution here?

The most interesting C++ question I've encountered recently goes as follows:
We determined (through profiling) that our algorithm spends a lot of time in debug mode in MS Visual Studio 2005 with functions of the following type:
MyClass f(void)
{
MyClass retval;
// some computation to populate retval
return retval;
}
As most of you probably know, the return here calls a copy constructor to pass out a copy of retval and then the destructor on retval. (Note: the reason release mode is very fast for this is because of the return value optimization. However, we want to turn this off when we debug so that we can step in and nicely see things in the debugger IDE.)
So, one of our guys came up with a cool (if slightly flawed) solution to this, which is, create a conversion operator:
MyClass::MyClass(MyClass *t)
{
// construct "*this" by transferring the contents of *t to *this
// the code goes something like this
this->m_dataPtr = t->m_dataPtr;
// then clear the pointer in *t so that its destruction still works
// but becomes 'trivial'
t->m_dataPtr = 0;
}
and also changing the function above to:
MyClass f(void)
{
MyClass retval;
// some computation to populate retval
// note the ampersand here which calls the conversion operator just defined
return &retval;
}
Now, before you cringe (which I am doing as I write this), let me explain the rationale. The idea is to create a conversion operator that basically does a "transfer of contents" to the newly constructed variable. The savings happens because we're no longer doing a deep copy, but simply transferring the memory by its pointer. The code goes from a 10 minute debug time to a 30 second debug time, which, as you can imagine, has a huge positive impact on productivity. Granted, the return value optimization does a better job in release mode, but at the cost of not being able to step in and watch our variables.
Of course, most of you will say "but this is abuse of a conversion operator, you shouldn't be doing this kind of stuff" and I completely agree. Here's an example why you shouldn't be doing it too (this actually happened:)
void BigFunction(void)
{
MyClass *SomeInstance = new MyClass;
// populate SomeInstance somehow
g(SomeInstance);
// some code that uses SomeInstance later
...
}
where g is defined as:
void g(MyClass &m)
{
// irrelevant what happens here.
}
Now this happened accidentally, i.e., the person who called g() should not have passed in a pointer when a reference was expected. However, there was no compiler warning (of course). The compiler knew exactly how to convert, and it did so. The problem is that the call to g() will (because we've passed it a MyClass * when it was expecting a MyClass &) called the conversion operator, which is bad, because it set the internal pointer in SomeInstance to 0, and rendered SomeInstance useless for the code that occured after the call to g(). ... and time consuming debugging ensued.
So, my question is, how do we gain this speedup in debug mode (which has as direct debugging time benefit) with clean code that doesn't open the possibility to make such other terrible errors slip through the cracks?
I'm also going to sweeten the pot on this one and offer my first bounty on this one once it becomes eligible. (50 pts)
You need to use something called "swaptimization".
MyClass f(void)
{
MyClass retval;
// some computation to populate retval
return retval;
}
int main() {
MyClass ret;
f().swap(ret);
}
This will prevent a copy and keep the code clean in all modes.
You can also try the same trick as auto_ptr, but that's more than a little iffy.
If your definition of g is written the same as in your code base I'm not sure how it compiled since the compiler isn't allowed to bind unnamed temporaries to non-const references. This may be a bug in VS2005.
If you make the converting constructor explicit then you can use it in your function(s) (you would have to say return MyClass(&retval);) but it won't be allowed to be called in your example unless the conversion was explicitly called out.
Alternately move to a C++11 compiler and use full move semantics.
(Do note that the actual optimization used is Named Return Value Optimization or NRVO).
The problem is occuring because you're using MyClass* as a magic device, sometimes but not always. Solution: use a different magic device.
class MyClass;
class TempClass { //all private except destructor, no accidental copies by callees
friend MyClass;
stuff* m_dataPtr; //unfortunately requires duplicate data
//can't really be tricked due to circular dependancies.
TempClass() : m_dataPtr(NULL) {}
TempClass(stuff* p) : m_dataPtr(p) {}
TempClass(const TempClass& p) : m_dataPtr(p) {}
public:
~TempClass() {delete m_dataPtr;}
};
class MyClass {
stuff* m_dataPtr;
MyClass(const MyClass& b) {
m_dataPtr = new stuff();
}
MyClass(TempClass& b) {
m_dataPtr = b.m_dataPtr ;
b.m_dataPtr = NULL;
}
~MyClass() {delete m_dataPtr;}
//be sure to overload operator= too.
TempClass f(void) //note: returns hack. But it's safe
{
MyClass retval;
// some computation to populate retval
return retval;
}
operator TempClass() {
TempClass r(m_dataPtr);
m_dataPtr = nullptr;
return r;
}
Since TempClass is almost all private (friending MyClass), other objects cannot create, or copy TempClass. This means the hack can only be created by your special functions when clearly told to, preventing accidental usage. Also, since this doesn't use pointers, memory can't be accidentally leaked.
Move semantics have been mentioned, you've agreed to look them up for education, so that's good. Here's a trick they use.
There's a function template std::move which turns an lvalue into an rvalue reference, that is to say it gives "permission" to move from an object[*]. I believe you can imitate this for your class, although I won't make it a free function:
struct MyClass;
struct MovableMyClass {
MyClass *ptr;
MovableMyClass(MyClass *ptr) : ptr(ptr) {}
};
struct MyClass {
MyClass(const MovableMyClass &tc) {
// unfortunate, we need const reference to bind to temporary
MovableMyClass &t = const_cast<MovableMyClass &>(tc);
this->m_dataPtr = t.ptr->m_dataPtr;
t.ptr->m_dataPtr = 0;
}
MovableMyClass move() {
return MovableMyClass(this);
}
};
MyClass f(void)
{
MyClass retval;
return retval.move();
}
I haven't tested this, but something along those lines. Note the possibility of doing something const-unsafe with a MovableMyClass object that actually is const, but it should be easier to avoid ever creating one of those than it is to avoid creating a MyClass* (which you've found out is quite difficult!)
[*] Actually I'm pretty sure I've over-simplified that to the point of being wrong, it's actually about affecting what overload gets chosen rather than "turning" anything into anything else as such. But causing a move instead of a copy is what std::move is for.
A different approach, given your special scenario:
Change MyClass f(void) (or operator+) to something like the following:
MyClass f(void)
{
MyClass c;
inner_f(c);
return c;
}
And let inner_f(c) hold the actual logic:
#ifdef TESTING
# pragma optimize("", off)
#endif
inline void inner_f(MyClass& c)
{
// actual logic here, setting c to whatever needed
}
#ifdef TESTING
# pragma optimize("", on)
#endif
Then, create an additional build configurations for this kind of testing, in which TESTING is included in the preprocessor definitions.
This way, you can still take advantage of RVO in f(), but the actual logic will not be optimized on your testing build. Note that the testing build can either be a release build or a debug build with optimizations turned on. Either way, the sensitive parts of the code will not be optimized (you can use the #pragma optimize in other places too, of course - in the code above it only affects inner_f itself, and not code called from it).
Possible solutions
Set higher optimization options for the compiler so it optimizes out the copy construction
Use heap allocation and return pointers or pointer wrappers, preferably with garbage collection
Use the move semantics introduced in C++11; rvalue references, std::move, move constructors
Use some swap trickery, either in the copy constructor or the way DeadMG did, but I don't recommend them with a good conscience. An inappropriate copy constructor like that could cause problems, and the latter is a bit ugly and needs easily destructible default objects which might not be true for all cases.
+1: Check and optimize your copy constructors, if they take so long then something isn't right about them.
I would prefer to simply pass the object by reference to the calling function when MyClass is too big to copy:
void f(MyClass &retval) // <--- no worries !
{
// some computation to populate retval
}
Just simple KISS principle.
Okay I think I have a solution to bypass the Return Value Optimization in release mode, but it depends on the compiler and not guaranteed to work. It is based on this.
MyClass f (void)
{
MyClass retval;
MyClass dummy;
// ...
volatile bool b = true;
if b ? retval : dummy;
}
As for why the copy construction takes so long in DEBUG mode, I have no idea. The only possible way to speed it up while remaining in DEBUG mode is to use rvalue references and move semantics. You already discovered move semantics with your "move" constructor that accepts pointer. C++11 gives a proper syntax for this kind of move semantics. Example:
// Suppose MyClass has a pointer to something that would be expensive to clone.
// With move construction we simply move this pointer to the new object.
MyClass (MyClass&& obj) :
ptr (obj.ptr)
{
// We set the source object to some trivial state so it is easy to delete.
obj.ptr = NULL;
}
MyClass& operator = (MyClass&& obj) :
{
// Here we simply swap the pointer so the old object will be destroyed instead of the temporary.
std::swap(ptr, obj.ptr);
return *this;
}

force g++ to zero initialize memory

I want to write some unit tests of a library I'm writing
I have a class which looks like this one :
class A
{
public:
A(B* pB)
// construction details, involves my library
// but ultimately there is a new being done ,)
B* m_pB;
};
I'd like to check that the pointer m_pB is actually initialized, so I did something along these lines :
A* p = // creation of this object involves my library
BOOST_REQUIRE( p->m_pB != NULL );
but it happens g++ does not zero-initialize the memory, so the value of p->m_pB is just plain random. Is there a way to force g++ to zero initialize this memory for me when I new the object?
I believe Visual Studio does something similar with specific codes dependeing on where the memory is allocated.
edit: I can think of 2 backup solutions right now: using a smart pointer, or writing a new operator ...
Simply implement the default constructor. This guarantees that without passing an argument, the pointer is initialized to NULL.
class A
{
public:
A(B* pB)
// construction details, involves my library
// but ultimately there is a new being done ,)
A() : m_pB(NULL) {}
B* m_pB;
};
Or as Fritschy points out:
A() : m_pB() {}
Use an always-initializing class.
template<typename T> class always_initialized {
T t;
public:
operator T&() { return t; }
operator const T&() const { return t; }
always_initialized() : t() {}
always_initialized(const T& ref) : t(ref) {}
};
Edit: I see that most people didn't understand what this actually does. If you just set the pointer to NULL, then you have to do that separately in every constructor, and then you have to do that again for every variable, and it's also not generic for other POD things like POD structs. always_initialized is more maintainable, as you're not repeating yourself, more concise, and more generic, as it's good for any POD type or even non-POD type.
Did you consider making m_pB private and always initializing it in your constructors? By using encapsulation to enforce your class invariants you don't even need to do the kinds of checks you're implementing here.
Thanks for your answers, but I'd like a less invasive technique, as the classes are part of the test, and their constructor is right in the midle of the subject which is dependency injection.
I was just hopping for something similar to visual studio which sets the memory to some specific value in debug mode (I think?), through an option of g++ or something alike.
some answers/comments basically fall back to saying "don't test it, just don't make the mistake"
Finally, I've overloaded the new operator and added a call to memset(ptr, 0, size);
and I get my critical check p->m_pB != __null failed, it works fine.
you all get a +1 anyway, especially DeadMg for the interesting solution

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();
}
};