Ernst Murnleitner said:
Hello Readers,
Is there a way that only one class can construct a class A and its
inherited classes A2, A3 etc.?
I want to construct a class A (and the inherited classes A2, A3 etc.)
from a (factory) class Fa.
I wanted to make that only F can call
new A
Now, I could make the operator new a private member of A. But in this
case I would have to declare Fa also as friend for A2, A3 etc.
If I would use
protected:
static void * operator(size_t t);
all the classes A,A2, A3 also could construct A, A2, A3 ... objects.
Greetings
Ernst
I can't tell you how to get exactly what you want, but you can get close.
1. Define a structure in Fa that is private and declare a static variable of
that type inside Fa.
2. Make the constructor of A take a parameter of the private type described
in 1. This will mean that only Fa and friends of Fa will be able to
construct A and its derived classes.
3. Make A and its derived classes friends of Fa. This is necessary if you
are to define the constructors of A and its derived classes.
The problem with this scheme is in point 3. Once you make them friends of
Fa, A and its derived classes will be able to construct objects from the A
hierarchy. Yet you have to make them friends or else their constructors
can't be defined.
But this should not really be a problem. A derived class will only be able
to construct objects in the A hierarchy if you make that derived class a
friend of Fa. In that case you are presumably the author of the derived
class and hence can make sure that it doesn't construct any objects in the A
hierarchy. By contrast, if a client derives from A, then the derived class
will not be a friend of Fa and hence will not be able to construct any
objects in the A hierarchy.
An example is given below:
// forward declarations
class A;
class A1;
class A2;
class Fa
{
friend class A;
friend class A1;
friend class A2;
private:
struct Faprivate{};
static Faprivate fap;
public:
A* MakeA();
A1* MakeA1();
A2* MakeA2();
};
// definition of static member
Fa::Faprivate Fa::fap;
class A
{
public:
A(Fa::Faprivate fap)
{}
};
// Note that the constructor for A1 has a parameter of
// type Fa::Faprivate even though it would be possible to
// define a constructor for A1 that took no argument and used
// Fa's static member Fa::fap in the call to the base class
// constructor. The parameter is included to stop non-friends
// of Fa from constructing A1. Similar reasoning applies to A2.
class A1 : public A
{
public:
A1(Fa::Faprivate fap) : A(fap)
{}
};
class A2 : public A
{
public:
A2(Fa::Faprivate fap) : A(fap)
{}
};
// definitions for Fa's member functions
A* Fa::MakeA()
{
return new A(fap);
}
A1* Fa::MakeA1()
{
return new A1(fap);
}
A2* Fa::MakeA2()
{
return new A2(fap);
}
int main()
{
Fa fa;
A *pa = fa.MakeA();
A1*pa1 = fa.MakeA1();
A2*pa2 = fa.MakeA2();
return 0;
}