"jeffc" <> wrote in message news:<>...
> "Andy" <> wrote in message
> news: om...
> > >
> > > The point of making a constructor private is usually to NOT allow anyone
> to
> > > use it. (Imagine that instead of the "private" keyword it was
> > > "inaccessible".) ....
> >
> > Just one question - even the static creator function needs to create
> > an instance of the class on the heap or stack. Without a constructor
> > how can that be made possible. Or is it that everything is static and
> > the singleton is stateless? So we never need an instance. I think I am
> > missing something.
>
> What I wrote was a little misleading. When I said "NOT allow anyone to use
> it", I didn't mean literally anyone. I mean anyone *else* outside the
> class. The class itself can access its own private constructor. See Karl's
> answer. e.g.
I am sorry I made a stupid mistake. I was under the impression that
just as static functions cannot access instance data members of a
class, they also cannot call non-static member functions. Of course
member functions are not per instance even if they are made to look
that way. Constructor being a special kind of such a function should
be accessible from static member functions.
>
> class A
> {
> private:
> A() {}
> public:
> static A* createAnA();
> };
>
> A* A::createAnA()
> {
> return new A;
> }
>
> int main()
> {
> A* pA = A::createAnA();
> }
I was just wondering, though this is purely a design issue, what
happens to the pointer that we get from the CreateAnA creator
function. The client code will need to explicitly call "delete" on
this pointer -- not a good thing. We would perhaps need a manager
class in between which takes care of calling delete in its destructor
.... or may be something like an auto_ptr type smart and cocky pointer
pretenders.
The singleton
--------------
The code snippet that you gave does not serve a singleton though. How
do we do that. I tried doing it this way:
----->
#include <iostream>
class CPrivCons
{
private:
CPrivCons(int n) : m_nInt(n)
{
s_cRefCnt=0;
s_This = NULL;
}
int m_nInt;
static int s_cRefCnt;
static CPrivCons *s_This;
public:
static CPrivCons& CreateObj(int n)
{
if(s_cRefCnt==0){
std::cout<<"NewInstanceCreated"<<std::endl;
s_This = new CPrivCons(n);
}
s_cRefCnt++;
return *s_This;
}
static void DestroyObj()
{
if(--s_cRefCnt == 0){
std::cout<<"ObjectDestroyed"<<std::endl;
delete s_This;
}
}
int get_IntVal()
{
int n = m_nInt;
return n;
}
void set_IntVal(int n)
{
m_nInt = n;
}
};
int CPrivCons::s_cRefCnt = 0;
CPrivCons *CPrivCons::s_This = NULL;
int main()
{
CPrivCons& p = CPrivCons::CreateObj(10);
CPrivCons& p1 = CPrivCons::CreateObj(12);
std::cout<<p.get_IntVal()<<std::endl;
std::cout<<p1.get_IntVal()<<std::endl;;
p1.set_IntVal(19);
std::cout<<p.get_IntVal()<<std::endl;
CPrivCons:

estroyObj();
CPrivCons:

estroyObj();
return 0;
}
<-----
The above code can of course not be used in a multi-threaded
situation. Besides, I feel there should be a separate manager
interface interposed between the singleton and the client.
Cheers,
Andy