Other Names
Wrapper
Problem
An object is available that provides the services needed by a client, but the expected interface does not match, i.e. the prototypes of the object's member functions are not the same as the functions called by the client object.
Solution
Create an adapter object that implements the interface required by the client using the member functions provided by the server object. In this context the server object is called the adaptee.
Static Structure
The adapter can access the services of the adapteee either by private inheritance:

(in this case the adapter can simply call the services inherited from the adaptee:)
or by delegation:

In this case the adapter must contain an adaptee or a pointer to an adaptee, and explicitly delegate to it:
Each Windows window has a message queue, where Windows places user input messages such as "left mouse button down" or "arrow key pressed". Messages can also be placed there by controls, such as "OK button clicked" or "menu item selected".
Assume the following directives:
class MSGQueueImpl1: public MSGQueue,
public queue<MSG*>
{
public:
bool GetMessage(MSG*
lpMsg, int hWnd)
{
if (empty()) return false;
MSG* temp = front(); // top() fell out of VC++ 5.0!
if (temp->hWnd != hWnd) return false;
lpMsg = temp;
pop();
return true;
}
bool PeekMessage(MSG*
lpMsg, int hWnd)
{
if (empty()) return false;
MSG* temp = front();
if (temp->hWnd != hWnd) return false;
lpMsg = temp;
//pop();
return true;
}
void PostMessage(int
hWnd, int Msg)
{
MSG* msg = new MSG();
msg->hWnd = hWnd;
msg->message = Msg;
time(&(msg->qtime));
push(msg);
}
};
bool GetMessage(MSG*
lpMsg, int hWnd)
{
if (messages.empty()) return false;
MSG* temp = messages.front(); // top() fell out of VC++!
if (temp->hWnd != hWnd) return false;
lpMsg = temp;
messages.pop();
return true;
}
bool PeekMessage(MSG*
lpMsg, int hWnd)
{
if (messages.empty()) return false;
MSG* temp = messages.front();
if (temp->hWnd != hWnd) return false;
lpMsg = temp;
//pop();
return true;
}
void PostMessage(int
hWnd, int Msg)
{
MSG* msg = new MSG();
msg->hWnd = hWnd;
msg->message = Msg;
time(&(msg->qtime));
messages.push(msg);
}
private:
queue<MSG*>
messages;
};
q->PostMessage(42,
35);
q->PostMessage(15,
98);
q->PostMessage(93,
12);
if (q->PeekMessage(&msg,
42))
cout << msg;
if (q->GetMessage(&msg,
42))
cout << msg;
if (q->GetMessage(&msg,
15))
cout << msg;
return 0;
}
Actually, the queue template in the standard template library is already an adapter for deques or lists:
Problem
Here's a simple program that can be used to compute the average waiting times for a business in which no two customers overlap. It subtracts, adds, reads, writes, and casts objects belonging to a Time class:
int main()
{
Time arrived, served,
total;
char response;
int customers =
0;
bool more = true;
while(more)
{
cout << "enter arrival time: ";
cin >> arrived;
cout << "you entered: " << arrived << '\n';
customers += 1;
cout << "enter served time: ";
cin >> served;
cout << "you entered: " << served << " minutes\n";
Time diff = served - arrived;
cout << "difference = " << int(diff) << '\n';
total = total + diff;
cout << "total = " << int(total) << " minutes\n";
cout << "More? (y/n): ";
cin >> response;
more = response == 'y' || response == 'Y';
}
cout << "total
= " << int(total) << " minutes\n";
cout << "average
= " << double(total)/double(customers);
cout << "
minutes\n";
return 0;
}
class Minutes
{
public:
Minutes(int m =
0) { minutes = m; }
istream& read(istream&
is = cin);
ostream& write(ostream&
os = cout) const;
Minutes sub(const
Minutes& m) const;
Minutes add(const
Minutes& m) const;
int toInt() { return
minutes; }
double toDouble()
{ return double(minutes); }
private:
int minutes; //
elapsed minutes since midnight
};
#include <string>
using namespace std;
#include "minute.h"
// input format: HH:MM AM/PM
istream& Minutes::read(istream&
is /* = cin */)
{
int h; // elapsed
hours
int m; // elapsed
minutes
char c; // colon
string apm; //
am or pm
is >> h;
if (is.fail())
{
is.sync();
return is;
}
is >> c >> m;
if (c != ':' ||
is.fail())
{
is.sync();
is.setstate(ios::failbit);
return is;
}
is >> apm;
if (apm == "pm"
|| apm == "p.m." ||
apm == "PM" || apm == "P.M.")
if (h != 12) h += 12;
else if (apm ==
"am" || apm == "a.m." ||
apm == "AM" || apm == "A.M.")
if (h == 12) h = 0;
else
{
is.sync();
is.setstate(ios::failbit);
return is;
}
minutes = h * 60
+ m;
return is;
}
ostream& Minutes::write(ostream&
os /* = cout */) const
{
string colon;
int h = minutes/60;
int m = minutes
- h * 60;
if (m < 10)
colon = ":0"; else colon = ":";
if (h == 0)
os << 12 << colon << m << "AM";
else if (h > 12)
os << h - 12 << colon << m << "PM";
else if (h == 12)
os << h << colon << m << "PM";
else
os << h << colon << m << "AM";
return os;
}
Minutes Minutes::add(const Minutes&
m) const
{
return Minutes((minutes
+ m.minutes) % (24 * 60));
}
Minutes Minutes::sub(const Minutes&
m) const
{
return Minutes(minutes
- m.minutes);
}
