class SuperClass{
/* ==================== METHODS ======================================= */
void
setValue (
std::string name,
int i ) {
MemberMapIterator it = memberMap_.find ( name );
if ( it != memberMap_.end ( ) ) {
void* ptr = ( *it ).second;
long long classPtr = reinterpret_cast< long long > ( this );
long long memberPtr = reinterpret_cast< long long > ( ptr );
int* value = reinterpret_cast< int* > ( classPtr + memberPtr );
( *value ) = i;
}
} // setValue
int
getValue (
std::string name ) {
MemberMapIterator it = memberMap_.find ( name );
if ( it != memberMap_.end ( ) ) {
void* ptr = ( *it ).second;
long long classPtr = reinterpret_cast< long long > ( this );
long long memberPtr = reinterpret_cast< long long > ( ptr );
int* value = reinterpret_cast< int* > ( classPtr + memberPtr );
return *value;
}
return -234234;
} // getValue
protected:
/* ==================== METHODS ======================================= */
void
Build ( ) {
configure ( );
} // Build
void
AddMember (
std::string name,
void* ptr ) {
memberMap_.insert ( MemberMapPair ( name, ptr ) );
} // AddMember
/* ==================== STATIC METHODS======================================= */
virtual void
configure ( ) = 0;
private:
/* ==================== METHODS ======================================= */
/* ==================== DATA MEMBERS ======================================= */
MemberMap memberMap_;
};
class SubClass: public SuperClass {
public:
/* ==================== LIFECYCLE ======================================= */
SubClass( ) : age_ ( 0 ) {
Build ( );
} /* constructor */
~SubClass( ) /* destructor */
{ }
protected:
/* ==================== STATIC METHODS======================================= */
void
configure ( ) {
long long classPtr = reinterpret_cast< long long > ( this );
long long agePtr = reinterpret_cast< long long > ( &this->age_ );
void* ptr = reinterpret_cast< void* > ( agePtr - classPtr );
this->AddMember ( "age", ptr );
} // configure
private:
/* ==================== DATA MEMBERS ======================================= */
int age_;
}
在SubClass中,我将私有类字段的偏移量(将类视为C结构)添加到使用字符串名称作为键的超类映射。我将只执行一次配置然后我想使用此偏移量表示每个Person实例在运行时访问其私有字段(此+偏移=字段)。这样安全吗?我测试了这段代码,它正在做我想做的工作。但是我应该期待任何内存违规或其他东西(假设它不会是故意违规(程序员错误))?
答案 0 :(得分:1)
首先,值得知道 C ++类不像C结构。编译器会在vtable指针等类中添加额外的东西,这些指针可能位于开头,结尾或其他位置,具体取决于编译器。有一种类的行为类似于C结构(即一包位),它们被称为普通旧数据类型(POD)。你可以在StackOverflow上找到很多。由于您正在使用继承,因此您没有使用POD。
如果您试图强行访问私人会员,您可能需要重新设计您的设计。你应该问问自己为什么他们首先是私人的。根据你在代码中看起来的样子,我可以想到更简单的方法:
setValue
和getValue
虚拟并在子类中覆盖它。