InterviewSolution
| 1. |
Solve : c++ methods? |
|
Answer» There was an example, I can't seem to find now, but maybe someone can help me out. If I return this: (error: 'this' is unavailable for static member functions)it cannot be a static function. You want it to be an instance method. *Fires up VC++* For C++, you have to use pointers, rather then heap-allocated class instances. There are of course differences between references and pointers. Personally I've never used references except where required by an API or as a parameter where I needed to manipulate the parameter's value rather then the class instance it pointed to. in my quick test project, I used a very basic concept that was easy to implement- just a silly little class that wraps addition multiplication and subtraction into a PACKAGE: Code: [Select]#include <iostream> using namespace std; class BasicNumber { public: float Value; BasicNumber(float initvalue) { Value=initvalue; } BasicNumber* Add(float addvalue) { return new BasicNumber(Value+addvalue); } BasicNumber* Subtract(float minusvalue) { return new BasicNumber(Value-minusvalue); } BasicNumber* Multiply(float Multiplyvalue) { return new BasicNumber(Value * Multiplyvalue); } }; int _tmain(int argc, _TCHAR* argv[]) { BasicNumber* xnumber = new BasicNumber(40); BasicNumber* ynumber = xnumber->Add(5); BasicNumber* znumber = ynumber->Multiply(3); cout << xnumber->Value << endl; cout << ynumber->Value << endl; cout << znumber->Value << endl; int tempreturn; cin >> tempreturn; } that segment in the main function, if we were only interested in "znumber" could have been: Code: [Select]BasicNumber* znumber = new BasicNumber(40)->Add(5)->Multiply(3); Basically, each method returns a new instance of the class; this is pretty common practice in the case of immutable objects, for example, it's usually done in the case of strings as well. In your case, you're trying to use static methods, so there will be no "instance" or "reference" to pass anywhere; there is no "this" pointer to return, as you've seen, and you cannot to my understanding pass a static "instance" of a class anywhere. In each algorithm, you are going to need to construct a new "Algorithm" class instance, to hold the result which you then return; if you are manipulating the single character array, then it would need to return the this pointer. Either way, the core methods will probably not be able to be static, if you want to be able to access them as you are suggesting. In fact, the way you have it wouldn't work, anyways; you're trying to return the instance variable "buffer" in a static method (Return); you would have to make the buffer static, in which case it's pointless to have a constructor since there isn't any class instance data to hold (I have no idea if static constructors are supported by C++ or how they might be used); in which case you are basically left with a few functions and some static variables. Basically, the static methods have nothing to work with; the Blowfish() function, for example, is no doubt supposed to encrypt something; but it has nothing to encrypt! the "buffer" field is a instance variable of the class, and the Blowfish() function is a static method and therefore there is no "instance" of the class for it to manipulate. Unless you want to start passing around unrelated structures of function pointers, it might be best to use a instance-method BASED approach. The basic idea of what you want is that each function should return a pointer to a class instance that contains the output data of the called method. Each method of the class would manipulate the data as it is present in that instance and return a new instance with the output data, etc. Similar to the Number example, but obviously a bit more complex; it might look something like this: Code: [Select]Algorithm* Resultalgo = new Algorithm(fileobject)->AES()->BlowFish(); Of course the various AES() and BlowFish() functions could have additional parameters to control encryption. After that, you would end up with a Algorithm Pointer that contains a buffer that is the result of the BlowFish of the AES of the fileobject. No doubt retrievable via a buffer member field, or something- the buffer being the "important" piece of data that each class instance manages. Looks nice. Is it efficient, as in, performance? And when you delete "Algorithm* Resultalgo" after use, it will remove everything related to the class, including the class pointers? Algorithm* Resultalgo = new Algorithm(fileobject)->AES()->BlowFish();Quote from: guss on February 08, 2011, 02:34:21 PM Looks nice. Is it efficient, as in, performance? It depends on how you implement it. If you use immutable classes (like the number example) where the methods basically would take their member "buffer" value and encrypt it, then return a entirely new class that has as it's buffer the result, then you will end up with quite a bit of duplication. In fact, I think it might even have a memory leak; in the BasicNumber* znumber=(new BasicNumber(40))->Add(5)->Multiply(3); case, I couldn't get the two "intermediate" class pointers to deallocate. I'm not sure if they did or not (could be an issue with cout and intermediate value destructors?), I was able to get the resulting znumber to deallocate, however, so I think maybe using pointers results in a memory leak of whatever member variables the class instance contains. In your case, an entire buffer. I was able to get it working with Heap-allocated class instances (so I was dead wrong in stating it couldn't be done that way, thankfully.) Code: [Select]#include <iostream> using namespace std; class BasicNumber { public: float Value; BasicNumber(float initvalue) { Value=initvalue; cout << "BasicNumber constructor, value=" << Value << endl; } ~BasicNumber() { cout << "BasicNumber destructor, value=" << Value << endl; } BasicNumber Add(float addvalue) { return BasicNumber(Value+addvalue); } BasicNumber Subtract(float minusvalue) { return BasicNumber(Value-minusvalue); } BasicNumber Multiply(float Multiplyvalue) { return BasicNumber(Value * Multiplyvalue); } }; void useroutine() { BasicNumber qnumber = BasicNumber(40).Add(5).Multiply(3); cout << qnumber.Value << endl; } int _tmain(int argc, _TCHAR* argv[]) { useroutine(); int tempreturn; cin >> tempreturn; } My original confusion resulted because I thought you needed to use new to create class instances, but you can simply omit the "new" operator and get a heap-allocated instance. (I believe you called them references, and I don't see how that name wouldn't apply). Basically this way is better because all the intermediate class instances have their destructors called. Not really necessary for "BasicNumber" but no doubt your Algorithm class would ideally deallocate it's buffer. Quote And when you delete "Algorithm* Resultalgo" after use, it will remove everything related to the class, including the class pointers?Nope just figured that out above. the intermediate pointers don't look like they get destroyed; deleting (in my example) "znumber" didn't cause any other destructors to run, and those intermediate pointers are essentially "orphaned" since there is no way to get at them. (that I know of). So it would seem that your original idea (with a few minor tweaks) would be the way to go. heap allocation is certainly preferred since the class will have it's destructor called when the variable goes out of scope.Thanks for examples and explanations. This will help a bunch.Maybe you can help me with this one. class 'Generic' is inherited by class 'Sudoku', and then use Printf() to print......this is mostly just for testing on a console application before moving it to a windows app, but hence its a 'Generic' Class.....or is there a better way of doing what I am trying to do? Code: [Select]class Generic { public: class Char { public: Char(); ~Char(); template <typename T> const char* Convert(T variable) { std::stringstream temp; temp << variable; return temp.str().c_str(); } template <typename T> void Printf(T variable) { printf(Convert(variable)); } }; template <typename T> class Transmitter { std::vector<T> v; public: Transmitter(); ~Transmitter(); Transmitter pushback_a(const T d[]) { for(int i=0; i<d.size(); ++i) v.push_back(d); } Transmitter pushback_v(const T &d) { v.push_back(d); } }; }; //-------------------------- Sudoku Game; for(int x = 0; x < 9; ++x) { for(int p = 0; p < 9; ++p) { Game.Char().Printf(Game.board[x][p]); } printf("\n"); } //-------------------------- error: invalid use of 'class Generic::Char'| |
|