Hi
I have a third party code.

class Lazy
{
protected:

  template <class T>
  static void create( T*& ptr ) 
  {  
    ptr = new T;
  }
};


template < class ClassT, 
		   class Policy=Lazy
         >
class MakeT : private Policy
{
public:

  static ClassT* instance()
  {
    static ClassT* ptr = 0;    
   
    if(!ptr)        
        Policy::create(ptr);
    
    return const_cast<ClassT*>(ptr);    
  }
};

Above is used to create new instance of a class.

What I could not understand here is class Lazy. Here why need to use such class? Why code

if(!ptr)        
  Policy::create(ptr);

could not replace with

if(!ptr)        
  ptr = new ClassT;

Why need of having Lazy class? And why *& used in

static void create( T*& ptr )

method

Thanks

Ok the class is a policy class. So let us understand what you can do with the original code and your code.

First consider two classes:

class SimpleObj
{
  // Stuff..
  public:
    SimpleObj();  // Simple default constructor
};

class ComplexState
{
  public:
    ComplexState(const int,const std::string&);   // THE ONLY CONSTRUCTOR
};

Now with your code, you cannot use ComplexState, there is not default constructor.

However, with the original code, let me add this:

class ComplexBuilder
{
public:

  // No need for template as it is specialized:
  static void create( ComplexState*& ptr ) 
  {  
    ptr = new T(3,"testfile");
  }
};

Now I can use your class like this:

MakeT<ComplexState,ComplexBuilder>::instance()->doStuff();

The reason for a reference, to a pointer, is that the pointer value itself changes.

If I have mis-understood your problem, or I am not clear, feel free to add a reply.

commented: bullseye! +1

Thnaks StuXYZ
Template Explanation is perfect.
But coukld you provide little more clarification about reference, to a pointer thing.
why they mix. what is the usage in what cases?

The reference to a pointer is not that difficult to understand once you understand that it is a reference to a type: Let us consider some examples to make the point

void func(int X)
{
   X=10;
   return;
}
int main()
{
   int y(20);
   func(y)
   // y still 20 here:
   std::cout<<"y == "<<y<<std::endl;   
}

In the simple code above, you can see that y doesn't change. So let us change func to this.

void func(int& X)
{  
   X=10;
   return;
}

Ok now, x get changes since it is a reference.

Well what about a pointer:

void func(int* X)
{
   *X=10;
}
int main()
{
   int y(20);
   func(&y);
}

Well you have to call that differently with that ADDRESS of y. But let us change it to this:

int main()
{
   int y;
   int *yPtr=&y; 
   func(yPtr);
   if (yPtr==&y)
     std::cout<<"yPtr unchanged";
}

But after the call yPtr STILL points to the address &y. What if you want to CHANGE a pointer, well it is just like changing a value, just that the pointer is the value.
You might like to write this:

void func(int*& XPtr)
{
   XPtr=new int[8];   // Allocate 8 int
   return;
}
int main()
{
   int* yPtr(0);
   func(yPtr);
   delete [] yPtr;         // yPtr == memory from a new.
}

As [hopefully] you can see, all a reference effectively does is allow access to a value as if it was in direct scope. So that you add a reference if you want to change and object, or if you don't want to make a copy, e.g. with a big class [although in that case use void func(const classname& ] Thus because the use of the pointer reference was to change the pointer value itself, a pointer reference was used.

Just to explain more :

@Op : you first question about the Policy::create(...)

The reason why thats there instead of simply just new classT is because of its flexibility.

When the user creates a MakeT class it could now specify how the class is created.
If it simply uses the new operator, then it could use the default Lazy class. Otherwise, for instance, the user may have a certain special way to create an object.
If so then he could simply say MakeT<Classt, SpecialWayToCreate> m; so now, each Classt is created using the SpecialWayToCreate. As you can see, this is much more flexible.


As for your second question : its called a reference-pointer. It enables the function
not only change the value the pointer points to, but also its address and where it points to.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.