从类外部访问私有虚函数

时间:2014-11-02 05:44:47

标签: c++ private-members

我知道,就良好的编程习惯而言,这是一个坏主意,但我一直试图解决一个相对困难的问题,并希望有一些见解。基本上我试图按如下方式输出类的所有成员:

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?显然,我可以改变环境以使其更容易,但这会破坏问题的目的。

1 个答案:

答案 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。它应该适用于编译器。