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) [quote author="main.cpp"] #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; } [/quote] 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 [quote author="compiler error"] 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. [/quote] I don't understand where the int*& (pointer to an address) comes from. Thank you, Andrew J. Leer
