Jump to content

  • Log In with Google      Sign In   
  • Create Account


#ActualServant of the Lord

Posted 05 November 2012 - 11:44 AM

I'm deleting in the destructor of controls class. Don't know if its enough. Something like this:

~cControls()
   {
	for(cControl *ctrl : this->listControls)
	 delete ctrl;
   }

That's correct.

You might want to return cControl as a pointer from your 'Create' functions as well.

//Creates a label and returns a pointer to it. cControls retains ownership, and the label will be destroyed in cControls' destructor.
cLabel *cControls::CreateLabel()
{
	 cLabel *newLabel = new cLabel(); //Should be replaced with smart pointers in the future.

	 this->AddControl(newLabel);

	 return newLabel;
}
(Because code blocks are currently messing up, I posted the code here)

However, what if you want to pass parameters to the cLabel's constructor? Since you *are* using C++11 (your for-range loop), you can use C++11's perfect forwarding like this:
//Creates a label and returns a pointer to it. cControls retains ownership, and the label will be destroyed in cControls' destructor.
template<typename Arg>
cLabel *cControls::CreateLabel(Arg &&arg)
{
	 cLabel *newLabel = new cLabel(std::forward<Arg>(arg));
	 this->AddControl(newLabel);
	
	 return newLabel;
}
Code here

And you can then pass the cLabel constructor arguments (any number of them) directly to CreateLabel:
myControls.CreateLabel("My text", Color(255,0,0), Style::Bold);
That would internally call 'cLabel("My text", Color(255,0,0), Style::Bold)' without cLabel having to change anything about it.

But, you could even go a step further, and make your CreateLabel() work for any class that derives from cControl.
//Creates a cControl and returns a pointer to it. cControls retains ownership, and the label will be destroyed in cControls' destructor.
template<typename ControlType, typename Arg>
ControlType *cControls::Create(Arg &&arg)
{
	 ControlType *newControl = new ControlType(std::forward<Arg>(arg));
	 this->AddControl(newControl);

	 return newControl;
}
Code here

And you can use it like this:
myControls.Create<cLabel>("My text", Color(255,0,0), Style::Bold);
myControls.Create<cLineEdit>("Default text", Characters::Letters | Characters::Numbers | Characters::Symbols);
cMenu *menu = myControls.Create<cMenu>({"First item", "Second item", "Third item"});
menu->DoSomething();
Code here
...and not need to write a new CreateX() function for each type of control you make. Posted Image

Those functions would've shared 90% of the same code anyway, and the 10% that is different can be handled by templates. Plus, if you ever wrap your code in a DLL, and later decide to create new cControl-derived classes specific to a certain project, you'd have to add new functions to cControls and recompile the DLL needlessly (with project-specific additions). But with this way, it's completely avoided. Posted Image

#6Servant of the Lord

Posted 05 November 2012 - 11:40 AM

I'm deleting in the destructor of controls class. Don't know if its enough. Something like this:

~cControls()
   {
	for(cControl *ctrl : this->listControls)
	 delete ctrl;
   }

That's correct.

You might want to return cControl as a pointer from your 'Create' functions as well.

//Creates a label and returns a pointer to it. cControls retains ownership, and the label will be destroyed in cControls' destructor.
cLabel *cControls::CreateLabel()
{
	 cLabel *newLabel = new cLabel(); //Should be replaced with smart pointers in the future.

	 this->AddControl(newLabel);

	 return newLabel;
}


However, what if you want to pass parameters to the cLabel's constructor? Since you *are* using C++11 (your for-range loop), you can use C++11's perfect forwarding like this:
//Creates a label and returns a pointer to it. cControls retains ownership, and the label will be destroyed in cControls' destructor.
template<typename Arg>
cLabel *cControls::CreateLabel(Arg &amp;amp;amp;&amp;amp;amp;arg)
{
	 cLabel *newLabel = new cLabel(std::forward<Arg>(arg));
	 this->AddControl(newLabel);
	
	 return newLabel;
}


And you can then pass the cLabel constructor arguments (any number of them) directly to CreateLabel:
myControls.CreateLabel("My text", Color(255,0,0), Style::Bold);

That would internally call 'cLabel("My text", Color(255,0,0), Style::Bold)' without cLabel having to change anything about it.

But, you could even go a step further, and make your CreateLabel() work for any class that derives from cControl.
//Creates a cControl and returns a pointer to it. cControls retains ownership, and the label will be destroyed in cControls' destructor.
template<typename ControlType, typename Arg>
ControlType *cControls::Create(Arg &amp;amp;amp;&amp;amp;amp;arg)
{
	 ControlType *newControl = new ControlType(std::forward<Arg>(arg));
	 this->AddControl(newControl);

	 return newControl;
}


And you can use it like this:
myControls.Create<cLabel>("My text", Color(255,0,0), Style::Bold);
myControls.Create<cLineEdit>("Default text", Characters::Letters | Characters::Numbers | Characters::Symbols);
cMenu *menu = myControls.Create<cMenu>({"First item", "Second item", "Third item"});
menu->DoSomething();

...and not need to write a new CreateX() function for each type of control you make. Posted Image

Those functions would've shared 90% of the same code anyway, and the 10% that is different can be handled by templates. Plus, if you ever wrap your code in a DLL, and later decide to create new cControl-derived classes specific to a certain project, you'd have to add new functions to cControls and recompile the DLL needlessly (with project-specific additions). But with this way, it's completely avoided. Posted Image

#5Servant of the Lord

Posted 05 November 2012 - 11:29 AM

I'm deleting in the destructor of controls class. Don't know if its enough. Something like this:

~cControls()
   {
	for(cControl *ctrl : this->listControls)
	 delete ctrl;
   }

That's correct.

You might want to return cControl as a pointer from your 'Create' functions as well.

//Creates a label and returns a pointer to it. cControls retains ownership, and the label will be destroyed in cControls' destructor.
cLabel *cControls::CreateLabel()
{
     cLabel *newLabel = new cLabel(); //Should be replaced with smart pointers in the future.

     this->AddControl(newLabel);

	 return newLabel;
}

However, what if you want to pass parameters to the cLabel's constructor? Since you *are* using C++11 (your for-range loop), you can use C++11's perfect forwarding like this:
//Creates a label and returns a pointer to it. cControls retains ownership, and the label will be destroyed in cControls' destructor.
template<typename Arg>
cLabel *cControls::CreateLabel(Arg &amp;amp;amp;&amp;amp;amp;arg)
{
	 cLabel *newLabel = new cLabel(std::forward<Arg>(arg));
	 this->AddControl(newLabel);
	
	 return newLabel;
}

And you can then pass the cLabel constructor arguments (any number of them) directly to CreateLabel:
myControls.CreateLabel("My text", Color(255,0,0), Style::Bold);
That would internally call 'cLabel("My text", Color(255,0,0), Style::Bold)' without cLabel having to change anything about it.

But, you could even go a step further, and make your CreateLabel() work for any class that derives from cControl.
//Creates a cControl and returns a pointer to it. cControls retains ownership, and the label will be destroyed in cControls' destructor.
template<typename ControlType, typename Arg>
ControlType *cControls::Create(Arg &amp;amp;amp;&amp;amp;amp;arg)
{
	 ControlType *newControl = new ControlType(std::forward<Arg>(arg));
	 this->AddControl(newControl);

	 return newControl;
}

And you can use it like this:
myControls.Create<cLabel>("My text", Color(255,0,0), Style::Bold);
myControls.Create<cLineEdit>("Default text", Characters::Letters | Characters::Numbers | Characters::Symbols);
cMenu *menu = myControls.Create<cMenu>({"First item", "Second item", "Third item"});
menu->DoSomething();
...and not need to write a new CreateX() function for each type of control you make. Posted Image

Those functions would've shared 90% of the same code anyway, and the 10% that is different can be handled by templates. Plus, if you ever wrap your code in a DLL, and later decide to create new cControl-derived classes specific to a certain project, you'd have to add new functions to cControls and recompile the DLL needlessly (with project-specific additions). But with this way, it's completely avoided. Posted Image

#4Servant of the Lord

Posted 05 November 2012 - 11:28 AM

I'm deleting in the destructor of controls class. Don't know if its enough. Something like this:

~cControls()
   {
	for(cControl *ctrl : this->listControls)
	 delete ctrl;
   }

That's correct.

You might want to return cControl as a pointer from your 'Create' functions as well.

//Creates a label and returns a pointer to it. cControls retains ownership, and the label will be destroyed in cControls' destructor.
cLabel *cControls::CreateLabel()
{
     cLabel *newLabel = new cLabel(); //Should be replaced with smart pointers in the future.

     this->AddControl(newLabel);

	 return newLabel;
}

However, what if you want to pass parameters to the cLabel's constructor? Since you *are* using C++11 (your for-range loop), you can use C++11's perfect forwarding like this:
//Creates a label and returns a pointer to it. cControls retains ownership, and the label will be destroyed in cControls' destructor.
template<typename Arg>
cLabel *cControls::CreateLabel(Arg &amp;amp;&amp;amp;arg)
{
	 cLabel *newLabel = new cLabel(std::forward<Arg>(arg));
	 this->AddControl(newLabel);
	
	 return newLabel;
}

And you can then pass the cLabel constructor arguments (any number of them) directly to CreateLabel:
myControls.CreateLabel("My text", Color(255,0,0), Style::Bold);
That would internally call 'cLabel("My text", Color(255,0,0), Style::Bold)' without cLabel having to change anything about it.

But, you could even go a step further, and make your CreateLabel() work for any class that derives from cControl.
//Creates a cControl and returns a pointer to it. cControls retains ownership, and the label will be destroyed in cControls' destructor.
template<typename ControlType, typename Arg>
ControlType *cControls::Create(Arg &amp;amp;&amp;amp;arg)
{
	 ControlType *newControl = new ControlType(std::forward<Arg>(arg));
	 this->AddControl(newControl);

	 return newControl;
}

And you can use it like this:
myControls.Create<cLabel>("My text", Color(255,0,0), Style::Bold);
myControls.Create<cLineEdit>("Default text", Characters::Letters | Characters::Numbers | Characters::Symbols);
cMenu *menu = myControls.Create<cMenu>({"First item", "Second item", "Third item"});
menu->DoSomething();
...and not need to write a new CreateX() function for each type of control you make. Posted Image

Those functions would've shared 90% of the same code anyway, and the 10% that is different can be handled by templates. Plus, if you ever wrap your code in a DLL, and later decide to create new cControl-derived classes specific to a certain project, you'd have to add new functions to cControls and recompile the DLL needlessly (with project-specific additions). But with this way, it's completely avoided. Posted Image

#3Servant of the Lord

Posted 05 November 2012 - 11:28 AM

I'm deleting in the destructor of controls class. Don't know if its enough. Something like this:

~cControls()
   {
	for(cControl *ctrl : this->listControls)
	 delete ctrl;
   }

That's correct.

You might want to return cControl as a pointer from your 'Create' functions as well.

//Creates a label and returns a pointer to it. cControls retains ownership, and the label will be destroyed in cControls' destructor.
cLabel *cControls::CreateLabel()
{
     cLabel *newLabel = new cLabel(); //Should be replaced with smart pointers in the future.

     this->AddControl(newLabel);

	 return newLabel;
}

However, what if you want to pass parameters to the cLabel's constructor? Since you *are* using C++11 (your for-range loop), you can use C++11's perfect forwarding like this:
//Creates a label and returns a pointer to it. cControls retains ownership, and the label will be destroyed in cControls' destructor.
template<typename Arg>
cLabel *cControls::CreateLabel(Arg &amp;&amp;arg)
{
	 cLabel *newLabel = new cLabel(std::forward<Arg>(arg));
	 this->AddControl(newLabel);
	
	 return newLabel;
}

And you can then pass the cLabel constructor arguments (any number of them) directly to CreateLabel:
myControls.CreateLabel("My text", Color(255,0,0), Style::Bold);
That would internally call 'cLabel("My text", Color(255,0,0), Style::Bold)' without cLabel having to change anything about it.

But, you could even go a step further, and make your CreateLabel() work for any class that derives from cControl.
//Creates a cControl and returns a pointer to it. cControls retains ownership, and the label will be destroyed in cControls' destructor.
template<typename ControlType, typename Arg>
ControlType *cControls::Create(Arg &amp;&amp;arg)
{
	 ControlType *newControl = new ControlType(std::forward<Arg>(arg));
	 this->AddControl(newControl);

	 return newControl;
}

And you can use it like this:
myControls.Create<cLabel>("My text", Color(255,0,0), Style::Bold);
myControls.Create<cLineEdit>("Default text", Characters::Letters | Characters::Numbers | Characters::Symbols);
cMenu *menu = myControls.Create<cMenu>({"First item", "Second item", "Third item"});
menu->DoSomething();
...and not need to write a new CreateX() function for each type of control you make. Posted Image

Those functions would've shared 90% of the same code anyway, and the 10% that is different can be handled by templates. Plus, if you ever wrap your code in a DLL, and later decide to create new cControl-derived classes specific to a certain project, you'd have to add new functions to cControls and recompile the DLL needlessly (with project-specific additions). But with this way, it's completely avoided. Posted Image

#2Servant of the Lord

Posted 05 November 2012 - 11:28 AM

I'm deleting in the destructor of controls class. Don't know if its enough. Something like this:

~cControls()
   {
	for(cControl *ctrl : this->listControls)
	 delete ctrl;
   }

That's correct.

You might want to return cControl as a pointer from your 'Create' functions as well.

//Creates a label and returns a pointer to it. cControls retains ownership, and the label will be destroyed in cControls' destructor.
cLabel *cControls::CreateLabel()
{
     cLabel *newLabel = new cLabel(); //Should be replaced with smart pointers in the future.

     this->AddControl(newLabel);

	 return newLabel;
}

However, what if you want to pass parameters to the cLabel's constructor? Since you *are* using C++11 (your for-range loop), you can use C++11's perfect forwarding like this:
//Creates a label and returns a pointer to it. cControls retains ownership, and the label will be destroyed in cControls' destructor.
template<typename Arg>
cLabel *cControls::CreateLabel(Arg &amp;&amp;arg)
{
	 cLabel *newLabel = new cLabel(std::forward<Arg>(arg));
	 this->AddControl(newLabel);
	
	 return newLabel;
}

And you can then pass the cLabel constructor arguments (any number of them) directly to CreateLabel:
myControls.CreateLabel("My text", Color(255,0,0), Style::Bold);
That would internally call 'cLabel("My text", Color(255,0,0), Style::Bold)' without cLabel having to change anything about it.

But, you could even go a step further, and make your CreateLabel() work for any class that derives from cControl.
//Creates a cControl and returns a pointer to it. cControls retains ownership, and the label will be destroyed in cControls' destructor.
template<typename ControlType, typename Arg>
ControlType *cControls::Create(Arg &amp;&amp;arg)
{
	 ControlType *newControl = new ControlType(std::forward<Arg>(arg));
	 this->AddControl(newControl);

	 return newControl;
}

And you can use it like this:
myControls.Create<cLabel>("My text", Color(255,0,0), Style::Bold);
myControls.Create<cLineEdit>("Default text", Characters::Letters | Characters::Numbers | Characters::Symbols);
cMenu *menu = myControls.Create<cMenu>({"First item", "Second item", "Third item"});
menu->DoSomething();
...and not need to write a new CreateX() function for each type of control you make. Posted Image

Those functions would've shared 90% of the same code anyway, and the 10% that is different can be handled by templates. Plus, if you ever wrap your code in a DLL, and later decide to create new cControl-derived classes specific to a certain project, you'd have to add new functions to cControls and recompile the DLL needlessly (with project-specific additions). But with this way, it's completely avoided. Posted Image

PARTNERS