jeffc said:
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