Wednesday, 27 October 2010

'new operator' throw and nothrow

I used to always think and while coding take care that to check if memory allocation is successful, we need to check if the returned pointer is not NULL. Well, in MSVC8 this may not necessarily be true. Depending on the library you include (see here) you may end up with either a throw or a NULL. The partial good news is that you can in future write your code to not throw memory alloc failure. See example:



//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
#include<iostream>

using namespace
std;

int
main()
{

try

{

char
* p = new char[0x7fffffff];
if
(!p)
{

cout<<"Memory allocation for q failed. NULL returned."<<endl;
}
}

catch
(...)
{

cout<<"Exception caught by ..."<<endl;
}


char
* q = new (std::nothrow) char[0x7fffffff];
if
(!q)
{

cout<<"Memory allocation for q failed. NULL returned."<<endl;
}


return
0;
}




The output is as follows:

Wednesday, 20 October 2010

Memory Allocation for char*

One common problem that I have noticed is that people copy char* pointers thinking that the pointers will be valid when used but this is rarely the case. See the example below.


//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
//Example demonstrates allocation of memory for char*
#include<iostream>

using namespace
std;

typedef struct
{
char
const * name;
}
TypeInfo;

TypeInfo* MakeType(const char *typeName)
{

TypeInfo* newNamedTypeInfo = new TypeInfo;

char
* newTypeName = new char[strlen(typeName) + 1];
strcpy(newTypeName, typeName);
newNamedTypeInfo->name = newTypeName;

return
newNamedTypeInfo;
}


int
main()
{

TypeInfo* testType = MakeType("Apple Banana");
cout << "testType->name = " << testType->name << endl;

return
0;
}





Please suggest any improvements.

The output is as follows:
Note that there is a memory leak in the program if you can spot it and fix it then you are already half way through :)

Wednesday, 13 October 2010

C++ example of Proxy Design Pattern

The Proxy pattern is used when you need to represent a complex object by a simpler one. If creating an object is expensive in time or computer resources, Proxy allows you to postpone this creation until you need the actual object. A Proxy usually has the same methods as the object it represents, and once the object is loaded, it passes on the method calls from the Proxy to the actual object.

There are several cases where a Proxy can be useful:

1. If an object, such as a large image, takes a long time to load.
2. If the object is on a remote machine and loading it over the network may be slow, especially during peak network load periods.
3. If the object has limited access rights, the proxy can validate the access permissions for that user.

Proxies can also be used to distinguish between requesting an instance of an object and the actual need to access it. For example, program initialization may set up a number of objects which may not all be used right away. In that case, the proxy can load the real object only when it is needed.


The Proxy provides a surrogate or place holder to provide access to an object. A check or bank draft is a proxy for funds in an account. A check can be used in place of cash for making purchases and ultimately controls access to cash in the issuer’s account.



The frequency of use of Proxy is medium high

Lets look at the example below. Note that the actual Math class is created in the MathProxy when math operations need to be performed.



//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
//Proxy is part of Structural Patterns
//Structural Patterns deal with decoupling the interface and implementation of classes and objects
//A Proxy provides a surrogate or placeholder for another object to control access to it.

//The example we consider here a math class
//The proxy provides an interface but the real class is only initiated when it is used

#include<iostream>
#include<string>

using namespace
std;


// The 'Subject interface
class IMath
{

public
:
virtual
double Add(double x, double y) = 0;
virtual
double Sub(double x, double y) = 0;
virtual
double Mul(double x, double y) = 0;
virtual
double Div(double x, double y) = 0;
};


// The 'RealSubject' class
class Math : public IMath
{

public
:
double
Add(double x, double y)
{

return
x + y;
}

double
Sub(double x, double y)
{

return
x - y;
}

double
Mul(double x, double y)
{

return
x * y;
}

double
Div(double x, double y)
{

return
x / y;
}
};


// The 'Proxy Object' class
class MathProxy : public IMath
{

public
:
MathProxy()
{

math_ = NULL;
}

virtual
~MathProxy()
{

if
(math_)
delete
math_;
}

double
Add(double x, double y)
{

return
getMathInstance()->Add(x, y);
}

double
Sub(double x, double y)
{

return
getMathInstance()->Sub(x, y);
}

double
Mul(double x, double y)
{

return
getMathInstance()->Mul(x, y);
}

double
Div(double x, double y)
{

return
getMathInstance()->Div(x, y);
}

private
:
Math* math_;
Math* getMathInstance(void)
{

if
(!math_)
math_ = new Math();
return
math_;
}
};


//The Main method
int main()
{

// Create math proxy
MathProxy proxy;

//Do the math
cout<<"4 + 2 = "<<proxy.Add(4, 2)<<endl;
cout<<"4 - 2 = "<<proxy.Sub(4, 2)<<endl;
cout<<"4 * 2 = "<<proxy.Mul(4, 2)<<endl;
cout<<"4 / 2 = "<<proxy.Div(4, 2)<<endl;

return
0;
}



The output is as follows:



For more information see:

http://sourcemaking.com/design_patterns/proxy

http://www.patterndepot.com/put/8/proxy.pdf

http://www.dofactory.com/Patterns/PatternProxy.aspx

Wednesday, 6 October 2010

C++ example of Flyweight Design Pattern

The Flyweight pattern describes how to share objects to allow their use at fine granularities without prohibitive cost. Each “flyweight” object is divided into two pieces: the state-dependent (extrinsic) part, and the state-independent (intrinsic) part. Intrinsic state is stored (shared) in the Flyweight object. Extrinsic state is stored or computed by client objects, and passed to the Flyweight when its operations are invoked.


The Ant, Locust, and Cockroach classes can be “light-weight” because their instance-specific state has been de-encapsulated, or externalized, and must be supplied by the client.
The frequency of use of the flyweight pattern is low.
The following example illustrates the Flyweight pattern:




//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
//Flyweight is part of Structural Patterns
//Structural Patterns deal with decoupling the interface and implementation of classes and objects
//A Flyweight uses sharing to support large numbers of fine-grained objects efficiently.

//We will take an example of charachter class. Each charachter is unique and can have different size
//but the rest of the features will remain the same.

#include<iostream>
#include<string>
#include<map>

using namespace
std;

// The 'Flyweight' abstract class
class Character
{

public
:
virtual
void Display(int pointSize) = 0;

protected
:
char
symbol_;
int
width_;
int
height_;
int
ascent_;
int
descent_;
int
pointSize_;
};


// A 'ConcreteFlyweight' class
class CharacterA : public Character
{

public
:
CharacterA()
{

symbol_ = 'A';
width_ = 120;
height_ = 100;
ascent_ = 70;
descent_ = 0;
pointSize_ = 0; //initialise
}
void
Display(int pointSize)
{

pointSize_ = pointSize;
cout<<symbol_<<" (pointsize "<<pointSize_<<" )"<<endl;
}
};


// A 'ConcreteFlyweight' class
class CharacterB : public Character
{

public
:
CharacterB()
{

symbol_ = 'B';
width_ = 140;
height_ = 100;
ascent_ = 72;
descent_ = 0;
pointSize_ = 0; //initialise
}
void
Display(int pointSize)
{

pointSize_ = pointSize;
cout<<symbol_<<" (pointsize "<<pointSize_<<" )"<<endl;
}
};


//C, D, E,...

// A 'ConcreteFlyweight' class
class CharacterZ : public Character
{

public
:
CharacterZ()
{

symbol_ = 'Z';
width_ = 100;
height_ = 100;
ascent_ = 68;
descent_ = 0;
pointSize_ = 0; //initialise
}
void
Display(int pointSize)
{

pointSize_ = pointSize;
cout<<symbol_<<" (pointsize "<<pointSize_<<" )"<<endl;
}
};


// The 'FlyweightFactory' class
class CharacterFactory
{

public
:
virtual
~CharacterFactory()
{

while
(!characters_.empty())
{

map<char, Character*>::iterator it = characters_.begin();
delete
it->second;
characters_.erase(it);
}
}

Character* GetCharacter(char key)
{

Character* character = NULL;
if
(characters_.find(key) != characters_.end())
{

character = characters_[key];
}

else

{

switch
(key)
{

case
'A':
character = new CharacterA();
break
;
case
'B':
character = new CharacterB();
break
;
//...
case 'Z':
character = new CharacterZ();
break
;
default
:
cout<<"Not Implemented"<<endl;
throw
("Not Implemented");
}

characters_[key] = character;
}

return
character;
}

private
:
map<char, Character*> characters_;
};



//The Main method
int main()
{

string document = "AAZZBBZB";
const
char* chars = document.c_str();

CharacterFactory* factory = new CharacterFactory;

// extrinsic state
int pointSize = 10;

// For each character use a flyweight object
for(size_t i = 0; i < document.length(); i++)
{

pointSize++;
Character* character = factory->GetCharacter(chars[i]);
character->Display(pointSize);
}


//Clean memory
delete factory;

return
0;
}