Showing posts with label Reinterpret Cast. Show all posts
Showing posts with label Reinterpret Cast. Show all posts

C++ example of State Design Pattern


The State pattern allows an object to change its behavior when its internal state changes. This pattern can be observed in a vending machine. Vending machines have states based on the inventory, amount of currency deposited, the ability to make change, the item selected, etc. When currency is deposited and a selection is made, a vending machine will either deliver a product and no change, deliver a product and change, deliver no product due to insufficient currency on deposit, or deliver no product due to inventory depletion.

The frequency of use of State Pattern is Medium but is very useful and frequently used Telecoms Protocols implementation.

Example as follows:


//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
//State is part of Behavioral Patterns
//Behavioral Patterns deal with dynamic interactions among societies of classes and objects
//State allows an object to alter its behavior when its internal state changes.
// The object will appear to change its class

//We will take an example Bank card where depending on the deposit the customers status changes


#include<iostream>
#include<string>
#include "main.h"


Account* State::GetAccount(void)
{

return
account_;
}

void
State::SetAccount(Account* account)
{

account_ = account;
}


double
State::GetBalance(void)
{

return
balance_;
}


void
State::SetBalance(double balance)
{

balance_ = balance;
}


string State::GetStateName(void)
{

return
stateName_;
}


RedState::RedState(State* state)
{

this
->balance_ = state->GetBalance();
this
->account_ = state->GetAccount();
Initialise();
}


void
RedState::Deposit(double amount)
{

balance_ += amount;
StateChangeCheck();
}


void
RedState::Withdraw(double amount)
{

double
newAmount = amount + serviceFee_;
if
(balance_ - newAmount < lowerLimit_)
cout<<"No funds available for withdrawal!"<<endl;
else

balance_ -= newAmount;
}


void
RedState::PayInterest()
{

//No interest is paid
}

void
RedState::StateChangeCheck()
{

if
(balance_ > upperLimit_)
{

account_->SetState(reinterpret_cast<State*>(new SilverState(this)));
delete this
;
return
;
}
}


void
RedState::Initialise()
{

stateName_ = "Red";
//Should come from a data source
interest_ = 0.0;
lowerLimit_ = -100.0;
upperLimit_ = 0.0;
serviceFee_ = 15.0;
}


SilverState::SilverState(State* state)
{

this
->balance_ = state->GetBalance();
this
->account_ = state->GetAccount();
Initialise();
}


SilverState::SilverState(double balance, Account* account)
{

this
->balance_ = balance;
this
->account_ = account;
Initialise();
}


void
SilverState::Deposit(double amount)
{

balance_ += amount;
StateChangeCheck();
}


void
SilverState::Withdraw(double amount)
{

balance_ -= amount;
StateChangeCheck();
}


void
SilverState::PayInterest()
{

balance_ = balance_ * interest_;
StateChangeCheck();
}


void
SilverState::StateChangeCheck()
{

if
(balance_ < lowerLimit_)
{

account_->SetState(reinterpret_cast<State*>(new RedState(this)));
delete this
;
return
;
}

else if
(balance_ > upperLimit_)
{

account_->SetState(reinterpret_cast<State*>(new GoldState(this)));
delete this
;
return
;
}
}


void
SilverState::Initialise()
{

stateName_ = "Silver";
//Should come from a data source
interest_ = 1.0;
lowerLimit_ = 0.0;
upperLimit_ = 1000.0;
}


GoldState::GoldState(State* state)
{

this
->balance_ = state->GetBalance();
this
->account_ = state->GetAccount();
Initialise();
}


void
GoldState::Deposit(double amount)
{

balance_ += amount;
StateChangeCheck();
}


void
GoldState::Withdraw(double amount)
{

balance_ -= amount;
StateChangeCheck();
}


void
GoldState::PayInterest()
{

balance_ = balance_ * interest_;
StateChangeCheck();
}


void
GoldState::StateChangeCheck()
{

if
(balance_ < 0.0)
{

account_->SetState(reinterpret_cast<State*>(new RedState(this)));
delete this
;
return
;
}

else if
(balance_ < lowerLimit_)
{

account_->SetState(reinterpret_cast<State*>(new SilverState(this)));
delete this
;
return
;
}

else if
(balance_ > upperLimit_)
{

cout<<"Your account is too big now. Please consider using Swiss banks"<<endl;
}
}


void
GoldState::Initialise()
{

stateName_ = "Gold";
//Should come from a data source
interest_ = 5.0;
lowerLimit_ = 1000.0;
upperLimit_ = 10000000.0;
}


Account::Account(string owner):owner_(owner)
{

state_ = reinterpret_cast<State*>(new SilverState(0.0, this)); //default
}

Account::~Account()
{

delete
state_;
}


double
Account::GetBalance(void)
{

return
state_->GetBalance();
}


void
Account::Deposit(double amount)
{

state_->Deposit(amount);
cout<<"Deposited $"<<amount<<endl;
cout<<"Balance $"<<GetBalance()<<endl;
cout<<"Status "<<state_->GetStateName()<<endl;
cout<<"\n";
}


void
Account::Withdraw(double amount)
{

state_->Withdraw(amount);
cout<<"Withdrew $"<<amount<<endl;
cout<<"Balance $"<<GetBalance()<<endl;
cout<<"Status "<<state_->GetStateName()<<endl;
cout<<"\n";
}


void
Account::PayInterest()
{

state_->PayInterest();
cout<<"Interest Paid --------"<<endl;
cout<<"Balance $"<<GetBalance()<<endl;
cout<<"Status "<<state_->GetStateName()<<endl;
cout<<"\n";
}


void
Account::SetState(State* state)
{

state_ = state;
}


State* Account::GetState(void)
{

return
state_;
}



//The Main method
int main()
{

Account* account = new Account("Dr. Who");
account->Withdraw(10.00);
account->Withdraw(30.00);
account->Withdraw(70.00);
account->Deposit(234.00);
account->Deposit(5000.00);
account->Withdraw(5200.00);
account->Deposit(1500.00);
account->Deposit(1.00);
account->Withdraw(1200.00);

delete
account;

return
0;
}



The output is as follows:

Further reading:

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




C++ example of Observer Design Pattern

Definition: Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.

Observers register themselves with the Subject as they are created. Whenever the Subject changes, it broadcasts to all registered Observers that it has changed.


The Observer defines a one-to-many relationship so that when one object changes state, the others are notified and updated automatically. Some auctions demonstrate this pattern. Each bidder possesses a numbered paddle that is used to indicate a bid. The auctioneer starts the bidding, and “observes” when a paddle is raised to accept the bid. The acceptance of the bid changes the bid price which is broadcast to all of the bidders in the form of a new bid.

Observer is a very popular pattern and its frequency of use is very high.

The following is an example of Observer Design Pattern:




//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
//Observer is part of Behavioral Patterns
//Behavioral Patterns deal with dynamic interactions among societies of classes and objects
//An Observer is a way of notifying change to a number of classes.

//We will take an example of Stock Price where, Observers can register to be told about
//the stock price change of a company

#include<iostream>
#include<string>
#include<list>

using namespace
std;


//Forward Declaration
class Stock;

// The 'Observer' interface
class IInvestor
{

public
:
virtual
void Update(Stock* stock){};
};


// The 'Subject' abstract class
class Stock
{

public
:
Stock(string symbol, double price) : symbol_(symbol), price_(price) { }
void
Attach(IInvestor* investor)
{

investors_.push_back(investor);
}

void
Detach(IInvestor* investor)
{

investors_.remove(investor);
}

void
Notify()
{

list<IInvestor*>::iterator it = investors_.begin();
while
(it != investors_.end())
{
(*
it)->Update(this);
++
it;
}
}

double
GetPrice(void)
{

return
price_;
}

void
SetPrice(double price)
{

price_ = price;
Notify();
}

string GetSymbol(void)
{

return
symbol_;
}


private
:
string symbol_;
double
price_;
list<IInvestor*> investors_;

Stock();
};


// The 'ConcreteSubject' class
class Company : public Stock
{

public
:
Company(string name, string symbol, double price) : name_(name), Stock(symbol, price) {}
string GetName(void)
{

return
name_;
}

private
:
string name_;
};


// The 'ConcreteObserver' class
class Investor : public IInvestor
{

public
:
Investor(string name) : name_(name){}
void
Update(Stock* stock)
{

cout<<"Notified "<<name_<<" about "<<(reinterpret_cast<Company*>(stock))->GetName() \
<<
" change to "<<stock->GetSymbol()<<stock->GetPrice()<<endl;
}

private
:
string name_;
Investor();
};


//The Main method
int main()
{

Company* c1 = new Company("Google", "$", 123.0);
cout<<"Created company Google with Stock Price 123.0\n"<<endl;

Investor* i1 = new Investor("Billy");
c1->Attach(i1);
cout<<"Created investor Billy following Google\n"<<endl;

c1->SetPrice(125.0);

Investor* i2 = new Investor("Timmy");
c1->Attach(i2);
Investor* i3 = new Investor("Lenny");
c1->Attach(i3);
cout<<"\nCreated investor Timmy and Lenny following Google\n"<<endl;

c1->SetPrice(145.0);

c1->Detach(i1);
c1->Detach(i3);
cout<<"\nInvestor Billy and Lenny not interested in Google anymore\n"<<endl;

c1->SetPrice(165.0);

delete
i1;
delete
i2;
delete
i3;
delete
c1;

return
0;
}



The output is as follows:
Further Reading:




reinterpret_cast in C++

From the Cpp Reference:

Syntax: TYPE reinterpret_cast (object);

The reinterpret_cast operator changes one data type into another. It should be used to cast between incompatible pointer types.

Suppose we have two variables, int a and char b

In C programming we can covert from b to a by:
a = (int)b;

In C++, the proper way to do this would be by using cast. One way is to use:
a = reinterpret_cast(b);

Most of the time reinterpret_cast is not required in the programs and can often be very dangerous. The following is from MSDN:

The reinterpret_cast operator also allows any integral type to be converted into any pointer type and vice versa. Misuse of the reinterpret_cast operator can easily be unsafe. Unless the desired conversion is inherently low-level, you should use one of the other cast operators.

The reinterpret_cast operator can be used for conversions such as char* to int*, or One_class* to Unrelated_class*, which are inherently unsafe.

The result of a reinterpret_cast cannot safely be used for anything other than being cast back to its original type. Other uses are, at best, nonportable.

The reinterpret_cast operator cannot cast away the const, volatile, or __unaligned attributes. See const_cast Operator for information on removing these attributes.

The reinterpret_cast operator converts a null pointer value to the null pointer value of the destination type.

One practical use of reinterpret_cast is in a hash function, which maps a value to an index in such a way that two distinct values rarely end up with the same index.

Instead of reinterpret_cast people generally prefer static_cast

Lets look at an example of reinterpret_cast:





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

using namespace
std;

int
main()
{

int
a = 22;
float
b = (float)33.3333;

cout<<"1. a = "<< a <<" b = "<< b <<endl;

a = (int)b; //Old C programming way
cout<<"2. a = "<< a <<" b = "<< b <<endl;

//Wont work in this case because floating point format is different
a = reinterpret_cast<int&>(b);
cout<<"3. a = "<< a <<" b = "<< b <<endl;

a = static_cast<int>(b); //Correct approach
cout<<"4. a = "<< a <<" b = "<< b <<endl;

char
c;
//Convert int to char
c = reinterpret_cast<char&>(a);
cout<<"5. c = "<< (int)c <<" a = "<< a <<endl;

//Dangerous to convert from char to int
a = reinterpret_cast<int&>(c);
cout<<"6. c = "<< (int)c <<" a = "<< a <<endl;

//What we actually wanted was just the last 8 bits so...
a = a & 0x000000FF; //00 = 8 bits
cout<<"7. c = "<< (int)c <<" a = "<< a <<endl;

return
0;
}






The output is as follows:

Check out this stream