我知道,就良好的编程习惯而言,这是一个坏主意,但我一直试图解决一个相对困难的问题,并希望有一些见解。基本上我试图按如下方式输出类的所有成员:
class protoCalc
{
private:
int x;
int y;
virtual int basicAddition()
{
return x + y;
}
virtual int basicMultiplication()
{
return x*y;
}
public:
protoCalc(){
x = 14;
y = 120;
}
};
访问x和y证明很容易;这样做我写了一个函数(包括我对它如何工作的想法,无论它们是否正确):
int private_member_Print(void* proto)
{
protoCalc* medium = (protoCalc*)proto;
protoCalc halfway = *medium;
int* ptr = ((int *)(&halfway));
return ptr[1];
}
上面将返回x的值,如果使用ptr [2],它将返回y的值。
现在我有两个问题,第一个是ptr [0]指向的是什么?不应该被私人成员x占用那段记忆,因为那是#protoCalc类的第一个成员吗?如果没有,那么占据这个地址的是什么?
其次,如何访问虚拟功能?我的第一个直觉是地址ptr [3]将被basicAddition()虚函数和ptr [4] basicMultiplication()函数占用,但事实并非如此。当这不成真时我的下一个想法是ptr [0]包含指向虚拟成员表的位置的指针,该表具有我正在寻找的两个函数。然而,这也被证明是错误的。
那么我如何访问类外的这些虚函数,因为我访问了私有成员x和y?显然,我可以改变环境以使其更容易,但这会破坏问题的目的。
答案 0 :(得分:0)
您目前正在做的是未定义的行为。在大多数情况下,内存中对象的布局由编译器决定,并且您不知道编译器将每个成员放在内存中的位置。
话虽如此,有一种方法可以实现这一点,就是你大量滥用模板。我强烈建议不要这样做,而是提供成员函数来访问所需的数据。
以下是此实例的一个示例。
#include <iostream>
class Priv {
private:
int i;
void print( ) {
std::cout << i << std::endl;
}
public:
Priv( ) : i( 100 ) {}
void print_pub( ) {
std::cout << "Public" << std::endl;
this->print( );
}
};
template<typename Tag>
struct result {
/* export it ... */
typedef typename Tag::type type;
static type ptr;
};
template<typename Tag>
typename result<Tag>::type result<Tag>::ptr;
template<typename Tag, typename Tag::type p>
struct rob : result<Tag> {
/* fill it ... */
struct filler {
filler() { result<Tag>::ptr = p; }
};
static filler filler_obj;
};
template<typename Tag, typename Tag::type p>
typename rob<Tag, p>::filler rob<Tag, p>::filler_obj;
struct Priv_f { typedef void ( Priv::*type )(); };
template class rob< Priv_f, &Priv::print >;
struct Priv_i { typedef int Priv::*type; };
template class rob< Priv_i, &Priv::i >;
int main( ) {
Priv p;
(p.*result<Priv_i>::ptr) = 1;
(p.*result<Priv_f>::ptr)();
}
可以找到rob {result模板类的说明here。它应该适用于编译器。