Nói về VC6, khi bạn chuyển một con trỏ của một lớp (mà bạn khởi tạo) thành một biến (ví dụ DWORD), ngay cả khi con trỏ này là cục bộ, bạn có thể truy cập lớp trên tất cả các hàm sử dụng cùng một heap. Lớp khởi tạo được định nghĩa là cục bộ nhưng thực tế thì không phải vậy. Theo như tôi biết, bất kỳ địa chỉ nào của một biến heap, cấu trúc hoặc lớp là duy nhất trong suốt vòng đời của lớp lưu trữ.
Thí dụ:
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;
}
EDIT Đó là một phần rất nhỏ của mã gốc. Lớp CSRecodset chỉ là một lớp đúc của CXdbRecordset, trong đó tất cả các mã thực sự là. Làm như vậy tôi có thể cho phép người dùng hưởng lợi từ những gì tôi đã viết mà không mất quyền. Tôi không giả vờ chứng minh rằng công cụ cơ sở dữ liệu của tôi là chuyên nghiệp nhưng nó thực sự hoạt động.
//-------------------------------------
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);
}
EDIT: được yêu cầu bởi DeadMG:
void nimportequoidumomentquecaroule(void) {
short i = -4;
unsigned short j=(unsigned short)i;
}