| ||||||||||||||||||||||||||
![]() |
|
|
«
Previous Thread
|
Next Thread
»
|
Thread Tools | Search this Thread | Display Modes |
|
#1
|
|||
|
|||
|
Dynamically use of classes instances
Hello;
I'm using a ADO database access to interact with a Microsoft Access database. Code:
_RecordsetPtr pRst("ADODB.Recordset");
// Connection String
_bstr_t strCnn("DRIVER={Microsoft Access Driver (*.mdb)};UID="";DBQ=testBroker.mdb");
// Open table
pRst->Open("SELECT value_d, tag FROM medidasDigitais ", strCnn, adOpenStatic, adLockReadOnly, adCmdText);
pRst->MoveFirst();
while (!pRst->EndOfFile) {
// this is key point where i want to get the tag
// and use methods associated with it
// note that the the instance of the class as been already
// initialized
(pRst->GetFields()->GetItem("tag")->GetValue()).ucState=(pRst->GetFields()->GetItem("value_d")->GetValue());
pRst->MoveNext();
}
pRst->Close();
I have this class with a method (.ucState) that allows to write to an internal variable. The point here is that i want to get instances names of classes directly from the database and have access to they're methods. The code provides a good understanding of what i am talking about. So is that even possible to be accomplished? Like if you have an instance of a class name in a string who as already been built. Can we use the content of the string to get access to the class methods/functions?? I hope I've been clear about my doubt. Thanks in advance; Luis |
|
#2
|
|||
|
|||
|
with c++ you can accompish anything
|
|
#3
|
|||
|
|||
|
Quote:
lol Ok, but the question is "how to" ?!?! |
|
#4
|
|||
|
|||
|
Larssss:
Anything your APIs and hardware allow you to. Don't include any files, and don't do declarations for things found in libraries, and you'll end up being able to do what? -Look at your input parameters and give a return value from main(). -Run a loop. -Other "fun" but ultimately useless stuff. ----- d_fly: Am I understanding this right? You have a MyClass my_object; in the source code and on retrieving the name "my_object" from the database, you want to be accessing it? (standard) C++ doesn't do reflection, so you'll have to fake it. (A compiler is free to support reflection in some fashion as an extension) map<string,MyClass*> available; The idea is that every object to be available in that fashion has to be entered with a name and a pointer to itself - and then a lookup is done with the name from the database, to try get the pointer to that object. (And yes, the name can then be different from its source code name) It's even possible to have no "named" objects, but dynamically allocating them and assigning them to be matched by a string. And THAT requires all of them to be of MyClass - if you also need heterogenous classes, there's a complexity cost. And make sure you can handle an invalid string in some fashion. Even if by a "controlled crash".
__________________
Quote:
Last edited by MaHuJa : July 5th, 2009 at 03:13 PM. Reason: Added link for std::map |
|
#5
|
|||
|
|||
|
Quote:
Amazing didn't had the clue that stuff like mapping existed!! It looks link it opens a brand new set of dynamic manipulation. Why don't they put this info on books or teach it in classes. Thanks allot MaHuJa. Now I'm trying to master the mapping, I hope I get it right. |
|
#6
|
|||
|
|||
|
OK, after spending the all afternoon trying out i got a nice understanding on how to achieve the dynamic use of class instances. Although it is far from being perfect i think it is a pretty well written piece of code, so i decided to share it and here it goes:
Code:
#include <iostream>
#include <map>
#include <string>
class CRectangle { // this a standard rectangle class see it on cplusplus.com/doc/tutorial/classes/
int *width, *height;
public:
int value; // this is as just a test variable that it is suposed to be manipulated dynamacly
CRectangle (int,int);
~CRectangle ();
int area () {return (*width * *height);}
};
CRectangle::CRectangle (int a, int b) {
width = new int;
height = new int;
value=0; // check this value is to be 0
*width = a;
*height = b;
}
CRectangle::~CRectangle () {
delete width;
delete height;
}
using namespace std;
int main(){
CRectangle *A; // we have to create pointers if we want to use the -> operator
A = new CRectangle (3,3); // and then lets construct the class instance
CRectangle *B;
B = new CRectangle (3,3);
CRectangle *C;
C = new CRectangle (3,3);
CRectangle *D;
D = new CRectangle (3,3);
string strCin;
map<string, CRectangle*> testMap; // Inicializate the map whose name is going to be testMap
testMap.insert(make_pair("A",A)); // .insert(PAIR TYPE HERE) receives type pair as input parameter
testMap.insert(make_pair("B",B)); // make pair creates a pair of string, CRectangle (in this case)
testMap.insert(make_pair("C",C));
testMap.insert(make_pair("D",D));
cout << "Enter wich rectangle do you want to know the area (A,B,C,D):" << endl;
cin >> strCin; // Instead of using a Cin we could get the value out of a database
map<string, CRectangle*>::iterator it = testMap.find(strCin);
// The .find() function returns an iterator to the matching key/value pair, or an iterator to the end of the map if key is not found.
cout << "First: " << it->first << " with size:" << it->first.length();
// now here it comes the best part, we can actually access the functions, methods of a mapped class, how?
// first find the class instance that you want with the find function already shown
// second, now that you have the index in the iterator (that in this case has the name "it") you can use the objects first and second
// to access the first type just do it->first and it will return the content of the string
// if you would want you could also do something like it->first.length() to get the lenght of the string
// we have the hability to use all of the functions associated to the class string
cout << it->second->area() << endl; // the second is the CRectangle in the map<string, CRectangle*>
// we have access to the method area() because we had designed in line 11 as public
cout <<"Value before: " <<it->second->value <<endl; // in the constructor the varaible value it is set to 0
// so lets see if we can also access to public variables
it->second->value=3; // but we changed its value dynamicly to be 3
cout << "Value after " <<it->second->value <<endl; // and this is it, wow
return 0;
/************************************************** ****************************************
************************************************** *****************************************
about: this is a test program written to demonstrate the use of maps on how to access
dynamacly created class instances, I hope it helps!!!
date: 06-07-2009
Author: Luis Mesquita
************************************************** *****************************************
************************************************** *****************************************/
}
Best regards; Luis ![]() |
|
#7
|
|||
|
|||
|
Code:
class CRectangle { // this a standard rectangle class see it on cplusplus.com/doc/tutorial/classes/
int *width, *height;
public:
int value; // this is as just a test variable that it is suposed to be manipulated dynamacly
CRectangle (int,int);
~CRectangle ();
int area () {return (*width * *height);}
};
That part set off alarms plenty. I looked at the referenced page, and it seems you didn't read the text or otherwise failed to understand how it was in order to demonstrate the importance of the destructor in classes that do dynamic allocation. I don't like demonstrations that show how to do X without showing a correct context for using X. At least without plenty warnings in code comments that this is not an appropriate scenario for using feature X. The reasons this is a bad idea are many. -On copying a CRectangle, both now refer to the same values - change one and you change the other. -On copying, both have ownership of the ints. When you get rid of them, you end up with a double delete. -Performance issues Allocating and deallocating those ints. -Accessing them is likely to be significantly slow(er) unless all the programs code and data fits in cpu cache. -It eats more memory. In fact, including memory allocation substructures, don't be surprised if it now requires 4-8 times more memory than the previous one. (Depending on C++ implementation, that is, which Compiler and settings) Code:
int main(){
CRectangle *A; // we have to create pointers if we want to use the -> operator
A = new CRectangle (3,3); // and then lets construct the class instance
Three things about those two lines. First of all, feel free to combine them like CRectangle *A = new CRectangle (3,3); Secondly, you forgot to delete A before you exited the function. See also "memory leak". Thirdly, you could just do CRectangle A(3,3); and later use the & address-of operator testMap.insert(make_pair("A",&A)); which would not be dynamic allocation, and hence not need you to remember deleting it. Or use a smart pointer to remember it for you. Code:
map<string, CRectangle*>::iterator it = testMap.find(strCin); // The .find() function returns an iterator to the matching key/value pair, or an iterator to the end of the map if key is not found. cout << "First: " << it->first << " with size:" << it->first.length(); Tested what happens when you give it E or some other value for which there is no mapping? if (it==testMap.end()) { cerr << "Not found"; return 1; } One could have shortened it down to CRectangle* x = testMap.find(strCin)->second; but that line can be expected to misbehave when strCin is not a valid key. Quote:
I'm speculating that the primary reason is that the teachers/writers don't know it themselves. Instead they usually teach you how to roll your own, which invariably turns out buggier and less fully featured. Not to mention it will take a lot more time. |
![]() |
| Viewing: Dev Articles Community Forums > Programming > C/C++ Help > Dynamically use of classes instances |
| Thread Tools | Search this Thread |
| Display Modes | Rate This Thread |
|
|
|
|