Hello,
I'm not entirely sure if this is even possible, but is it possible to
create a decorator pattern in C++ using template classes?
I've written some very basic source code to try and do this myself,
and I have posted it over at codepad.org (
http://codepad.org/EoxSD9AL)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
|
#include <iostream>
#include <string>
using namespace std;
/* Component (interface) */
class ServerCall {
public:
virtual int getsDataSize() = 0;
virtual ~ServerCall() {}
};
/* ConcreteComponent */
class CompanyServerCall : public ServerCall {
private:
protected:
public:
/*XXSocket *Socket;*/
CompanyServerCall(/* XXSocket *Sckt */){
/* Socket = Sckt; */
}
~CompanyServerCall() {
}
int getsDataSize() {
int ip = 0;
cout << "CompanyServerCall: " << "0 ";
cout << "ip: " << ip << endl;
return ip;
}
};
/* Decorator (interface) */
class ServerCallDecorator : public ServerCall {
private:
protected:
ServerCall* wid; // reference to ServerCall
public:
ServerCallDecorator( ServerCall* w ) {
wid = w;
}
int getsDataSize() {
return wid->getsDataSize();
}
~ServerCallDecorator() {
delete wid;
}
};
template <class T>
class TServerCallDecorator : public ServerCallDecorator {
private:
T *arg;
public:
TServerCallDecorator(T *shortArg, ServerCall* w ) :
ServerCallDecorator( w )
{
arg = shortArg;
}
int getsDataSize() {
int ip = ServerCallDecorator::getsDataSize();
cout << " ShortServerCallDecorator: " << *arg << ":";
/*memcpy(Socket->sData, arg, sizeof(T)); */
ip+=sizeof(T);
cout << " ip: " << ip << endl;
return ip;
}
};
// class template specifications
template <> class TServerCallDecorator <char> : public
ServerCallDecorator {
private:
char *arg;
public:
TServerCallDecorator(char *strArg, ServerCall* w ) :
ServerCallDecorator( w )
{
arg = strArg;
}
int getsDataSize() {
int ip = ServerCallDecorator::getsDataSize();
cout << " StringServerCallDecorator: " << arg << ";";
/*memcpy(Socket->sData+ip, arg, strlen(arg)+1) */
ip+=strlen(arg)+1;
cout << " ip: " << ip << endl;
return ip;
}
};
int main( void ) {
char *myStr = new char[20];
char *myStr2 = new char[20];
char *myStr3 = new char[50];
short *myShort = new short;
int *myInt = new int;
*myShort = 1;
*myInt = 4;
strcpy(myStr, "myStr");
strcpy(myStr2, "Tom");
strcpy(myStr3, "Andy");
CompanyServerCall* A = new CompanyServerCall(/* Socket */);
TServerCallDecorator<short> D (myShort, A);
TServerCallDecorator<int> E (myInt, D);
TServerCallDecorator<char> F (myStr, E);
cout << aServerCall->getsDataSize();
return 0;
}
|
What I wish to do is sum the total size of the data structure
needed to send some data over an imaginary socket, given a random set
of arguments (int this case myShort, myInt, and myStr) to pass to the
server on the other side.
All of the primitive data type sizes are calculated the same way
with the exception of the "char*" whose data type has to have 1 added
to its size for calculation (hence the template specification for the
<char> data type)
When I compile this code I get a strange error that reads
1 2 3 4 5 6 7
|
line 126: TServerCallDecorator<int> E (myInt, D);
In function 'int main()':
Line 126: error: no matching function for call to
'TServerCallDecorator<int>::TServerCallDecorator(int*&,
TServerCallDecorator<short int>&)'
compilation terminated due to -Wfatal-errors.
|
I don't understand where the int*& (pointer to an address) comes from.
Thank you,
Andrew J. Leer