Hablando de VC6, cuando convierte un puntero de una clase (que crea una instancia) en una variable (por ejemplo, DWORD), incluso si este puntero es local, puede acceder a la clase sobre todas las funciones que usan el mismo montón. La clase instanciada se define como local pero, de hecho, no lo es. Hasta donde sé, cualquier dirección de una variable, estructura o clase de montón es única a lo largo de toda la vida de la clase de alojamiento.
Ejemplo:
class MyClass1 {
public:
void A (void);
void B (void);
void C (void);
private:
DWORD dwclass;
};
class MyClass2 {
public:
int C (int i);
};
void MyClass1::A (void) {
MyClass2 *myclass= new MyClass2;
dwclass=(DWORD)myclass;
}
void MyClass1::B (void) {
MyClass2 *myclass= (MyClass2 *)dwclass;
int i = myclass->C(0); // or int i=((MyClass2 *)dwclass)->C(0);
}
void MyClass1::B (void) {
MyClass2 *myclass= (MyClass2 *)dwclass;
delete myclass;
}
EDITAR Esa es una muy pequeña parte del código original. La clase CSRecodset es solo una clase de conversión de CXdbRecordset, donde está todo el código real. Al hacerlo, puedo permitir que el usuario se beneficie de lo que escribí sin perder mis derechos. No pretendo demostrar que mi motor de base de datos es profesional, pero realmente funciona.
//-------------------------------------
class CSRecordSet : public CSObject
//-------------------------------------
{
public:
CSRecordSet();
virtual ~CSRecordSet();
// Constructor
bool Create(CSDataBase* pDataBase,CSQueryDef* pQueryDef);
//Open, find, close
int OpenRst(bool bReadBlanks=0,bool bCheckLastSql=0,bool bForceLoad=0,bool bMessage=1); // for a given SQL
int FindRecord(bool bNext); // for a given SQL
// TABLE must be ordered by the same fields that will be seek
bool SeekRecord(int nFieldIndex, char *key, int length=0); // CRT bsearch
bool SeekRecord(int nFieldIndex, long key);
bool SeekRecord(int nFieldIndex, double key, int decimals);
bool SeekRecord(XSEK *SEK);
bool DeleteRecord(void);
bool Close(void);
// Record Position:
bool IsEOF(void); // pointer out of bound
bool IsLAST(void); // TRUE if last record
bool IsBOF(void); // pointer out of bound
bool IsOpen(void);
bool Move(long lRows); // returns FALSE if out of bound
void MoveNextNotEof(void); // eof is tested
void MoveNext(void); // eof is not tested
void MovePrev(void); // bof is tested
void MoveLast(void);
void MoveFirst(void);
void SetAbsolutePosition(long lRows);
long GetAbsolutePosition(void);
void GoToLast(void); // Restore position after a Filter
// Table info
long GetRecordCount(void);
int GetRstTableNumber(void);
int GetRecordLength(void); //includes stamp (sizeof char)
int GetTableType(void);
// Field info
int GetFieldCount(void);
void GetFieldName(int nFieldIndex, char *pbuffer);
int GetFieldIndex(const char *sFieldName);
int GetFieldSize(int nFieldIndex);
int GetFieldDGSize(int nFieldIndex); // String size (i.e. dg_Boolean)
long GetRecordID(void);
int GetStandardFieldCount(void);
bool IsMemoFileTable(void);
bool IsNumberField(int nFieldIndex);
int GetFieldType(int nFieldIndex);
// Read Field value
bool GetFieldValue(int nFieldIndex, XdbVar& var);
bool GetFieldValueIntoBuffer(int nFieldIndex,char *pbuffer);
char *GetMemoField(int nMemoFieldIndex, char *pbuffer, int buf_size);
bool GetBinaryField(unsigned char *buffer,long *buf_size);
// Write Field value
void Edit(void); // required
bool SetFieldValue(int nFieldIndex, XdbVar& var);
bool SetFieldValueFromBuffer(int nFieldIndex,const char *pbuffer);
bool Update(void); // required
// pointer to the same lpSql
LPXSQL GetSQL(void);
};
//---------------------------------------------------
CSRecordSet::CSRecordSet(){
//---------------------------------------------------
pClass |= (CS_bAttach);
}
CSRecordSet::~CSRecordSet(){
if(pObject) delete (CXdbRecordset*)pObject;
}
bool CSRecordSet::Create(CSDataBase* pDataBase,CSQueryDef* pQueryDef){
CXdbQueryDef *qr=(CXdbQueryDef*)pQueryDef->GetObject();
CXdbTables *db=(CXdbTables*)pDataBase->GetObject();
CXdbRecordset *rst = new CXdbRecordset(db,qr);
if(rst==NULL) return 0;
pObject = (unsigned long) rst;
return 1;
}
bool CSRecordSet::Close(void){
return ((CXdbRecordset*)pObject)->Close();
}
int CSRecordSet::OpenRst(bool bReadBlanks,bool bCheckLastSql,bool bForceLoad, bool bMessage){
unsigned long dw=0L;
if(bReadBlanks) dw|=SQL_bReadBlanks;
if(bCheckLastSql) dw|=SQL_bCheckLastSql;
if(bMessage) dw|=SQL_bRstMessage;
if(bForceLoad) dw|=SQL_bForceLoad;
return ((CXdbRecordset*)pObject)->OpenEx(dw);
}
int CSRecordSet::FindRecord(bool bNext){
return ((CXdbRecordset*)pObject)->FindRecordEx(bNext);
}
bool CSRecordSet::DeleteRecord(void){
return ((CXdbRecordset*)pObject)->DeleteEx();
}
bool CSRecordSet::IsEOF(void){
return ((CXdbRecordset*)pObject)->IsEOF();
}
bool CSRecordSet::IsLAST(void){
return ((CXdbRecordset*)pObject)->IsLAST();
}
bool CSRecordSet::IsBOF(void){
return ((CXdbRecordset*)pObject)->IsBOF();
}
bool CSRecordSet::IsOpen(void){
return ((CXdbRecordset*)pObject)->IsOpen();
}
bool CSRecordSet::Move(long lRows){
return ((CXdbRecordset*)pObject)->MoveEx(lRows);
}
void CSRecordSet::MoveNextNotEof(void){
((CXdbRecordset*)pObject)->MoveNextNotEof();
}
void CSRecordSet::MoveNext(void){
((CXdbRecordset*)pObject)->MoveNext();
}
void CSRecordSet::MovePrev(void){
((CXdbRecordset*)pObject)->MovePrev();
}
void CSRecordSet::MoveLast(void){
((CXdbRecordset*)pObject)->MoveLast();
}
void CSRecordSet::MoveFirst(void){
((CXdbRecordset*)pObject)->MoveFirst();
}
void CSRecordSet::SetAbsolutePosition(long lRows){
((CXdbRecordset*)pObject)->SetAbsolutePosition(lRows);
}
long CSRecordSet::GetAbsolutePosition(void){
return ((CXdbRecordset*)pObject)->m_AbsolutePosition;
}
long CSRecordSet::GetRecordCount(void){
return ((CXdbRecordset*)pObject)->GetRecordCount();
}
int CSRecordSet::GetFieldCount(void){
return ((CXdbRecordset*)pObject)->GetFieldCount();
}
int CSRecordSet::GetRstTableNumber(void){
return ((CXdbRecordset*)pObject)->GetRstTableNumber();
}
void CSRecordSet::GetFieldName(int nFieldIndex, char *pbuffer){
((CXdbRecordset*)pObject)->GetFieldName(nFieldIndex,pbuffer);
}
int CSRecordSet::GetFieldIndex(const char *sFieldName){
return ((CXdbRecordset*)pObject)->GetFieldIndex(sFieldName);
}
bool CSRecordSet::IsMemoFileTable(void){
return ((CXdbRecordset*)pObject)->IsMemoFileTable();
}
bool CSRecordSet::IsNumberField(int nFieldIndex){
return ((CXdbRecordset*)pObject)->IsNumberField(nFieldIndex);
}
bool CSRecordSet::GetFieldValueIntoBuffer(int nFieldIndex,char *pbuffer){
return ((CXdbRecordset*)pObject)->GetFieldValueIntoBuffer(nFieldIndex,pbuffer);
}
void CSRecordSet::Edit(void){
((CXdbRecordset*)pObject)->Edit();
}
bool CSRecordSet::Update(void){
return ((CXdbRecordset*)pObject)->Update();
}
bool CSRecordSet::SetFieldValue(int nFieldIndex, XdbVar& var){
return ((CXdbRecordset*)pObject)->SetFieldValue(nFieldIndex,var);
}
bool CSRecordSet::SetFieldValueFromBuffer(int nFieldIndex,const char *pbuffer){
return ((CXdbRecordset*)pObject)->SetFieldValueFromBuffer(nFieldIndex,pbuffer);
}
bool CSRecordSet::GetFieldValue(int nFieldIndex, XdbVar& var){
return ((CXdbRecordset*)pObject)->GetFieldValue(nFieldIndex,var);
}
bool CSRecordSet::SeekRecord(XSEK *SEK){
return ((CXdbRecordset*)pObject)->TableSeek(SEK);
}
bool CSRecordSet::SeekRecord(int nFieldIndex,char *key, int length){
return ((CXdbRecordset*)pObject)->TableSeek(nFieldIndex,key,length);
}
bool CSRecordSet::SeekRecord(int nFieldIndex,long i){
return ((CXdbRecordset*)pObject)->TableSeek(nFieldIndex,i);
}
bool CSRecordSet::SeekRecord(int nFieldIndex, double d, int decimals)
{
return ((CXdbRecordset*)pObject)->TableSeek(nFieldIndex,d,decimals);
}
int CSRecordSet::GetRecordLength(void){
return ((CXdbRecordset*)pObject)->GetRecordLength();
}
char *CSRecordSet::GetMemoField(int nMemoFieldIndex,char *pbuffer, int BUFFER_SIZE){
return ((CXdbRecordset*)pObject)->GetMemoField(nMemoFieldIndex,pbuffer,BUFFER_SIZE);
}
bool CSRecordSet::GetBinaryField(unsigned char *buffer,long *buf_size){
return ((CXdbRecordset*)pObject)->GetBinaryField(buffer,buf_size);
}
LPXSQL CSRecordSet::GetSQL(void){
return ((CXdbRecordset*)pObject)->GetSQL();
}
void CSRecordSet::GoToLast(void){
((CXdbRecordset*)pObject)->GoToLast();
}
long CSRecordSet::GetRecordID(void){
return ((CXdbRecordset*)pObject)->GetRecordID();
}
int CSRecordSet::GetStandardFieldCount(void){
return ((CXdbRecordset*)pObject)->GetStandardFieldCount();
}
int CSRecordSet::GetTableType(void){
return ((CXdbRecordset*)pObject)->GetTableType();
}
int CSRecordSet::GetFieldType(int nFieldIndex){
return ((CXdbRecordset*)pObject)->GetFieldType(nFieldIndex);
}
int CSRecordSet::GetFieldDGSize(int nFieldIndex){
return ((CXdbRecordset*)pObject)->GetFieldDGSize(nFieldIndex);
}
int CSRecordSet::GetFieldSize(int nFieldIndex){
return ((CXdbRecordset*)pObject)->GetFieldSize(nFieldIndex);
}
EDITAR: solicitado por DeadMG:
void nimportequoidumomentquecaroule(void) {
short i = -4;
unsigned short j=(unsigned short)i;
}