【问题标题】:Accessing private members in a class访问类中的私有成员
【发布时间】:2012-01-25 18:13:06
【问题描述】:

我需要从 DLL 访问一个对象,对该对象进行一些操作并将该对象提供给另一个函数。问题是我需要更改的字段是私有的。

我不想更改原始类中字段的私有修饰符,因为该类是很久以前编写的,并且在很多地方都使用过。但是,在我操作类的地方,我需要大多数没有保护的字段(这是一个 hack)。最好的方法是什么?

注意:我不能更改原来的类

【问题讨论】:

  • 你所说的“这是一个黑客”是什么意思?如果您想在外部修改私有字段,您描述的方式看起来好像完全错误地处理了这个问题。
  • @templatetypedef-根据原始设计,不应访问字段,即使现在也是如此。但是我们现在有了一个新的 dll,并且以当前格式将对象传递给 dll 需要对 DLL 代码进行大量更改,这是我们想要避免的。
  • @confusedcoder:如果你不能修改类,这不能(安全/便携)完成。

标签: c++ class private-members


【解决方案1】:

在这种情况下,DLL 中编译的内容并不重要,重要的是您包含的头文件。我建议你把你感兴趣的类的头文件改成你需要的变量是public

成员访问由编译器而不是链接器检查,所以重要的是如何声明类。这要求您重新编译DLL或更改类的实现,而只需修改头文件(或头文件的副本)。

【讨论】:

  • 鉴于 OP 想要 hack 并准备好处理不可避免会导致的几天或几周的调试,这似乎是最好的 hack。
  • +1 ,我喜欢它,但一个问题是这会给将来研究代码的任何人造成混乱
  • @confusedcoder,hacks 就是 hacks...如果你在课堂上的更改旁边放了一个大注释,它应该可以帮助未来的维护者。
【解决方案2】:

如果你能看到原始类,你可以制作一个具有相同位模式的模拟类,并将原始对象转换为模拟类对象

以下示例

原班

class ClassWithHiddenVariables
{
private:
    int a;
    double m;

}; 

模拟类

 class ExposeAnotherClass
    {
    public:
        int a_exposed;
        double m_exposed;
    };

当您想查看 ClassWithHiddenVariables 对象的成员时,请使用 reinterpret_cast 强制转换为 ExposeAnotherClass

 ClassWithHiddenVariables obj;
    obj.SetVariables(10, 20.02);    
    ExposeAnotherClass *ptrExposedClass;
    ptrExposedClass = reinterpret_cast<ExposeAnotherClass*>(&obj);  
    cout<<ptrExposedClass->a_exposed<<"\n"<<ptrExposedClass->m_exposed;

【讨论】:

  • 是保证两个类相同的位模式
  • 如果您使用相同的编译器和设置,我认为可以。您可以检查类中是否有任何公共变量——只需检查原始对象的公共成员是否等于相应的模拟对象成员。
【解决方案3】:

一种方法:编写 Getter / Setter 函数

【讨论】:

  • 这并没有真正隐藏任何东西。那只是通过其他方式暴露他们。
  • @jisaak-但我不能更改原来的类。
  • @jisaak:然而它给每个人留下了一个很大的窗口来访问它们,因为 public 方法将被类的每个用户访问。这实际上破坏了封装。
  • Getter 和 setter 只比公共成员好一小步。一个真实的界面几乎总是首选。
  • @jisaak:,如果数据可以通过这些 getter/setter 完全访问,那么数据绝不“隐藏”。它完全可见。
【解决方案4】:

Exceptional C++ Style, Item 15 中的“Forger”破解将起作用。虽然,这是非法的,因为它违反了单一定义规则,所以我建议不要在生产代码中这样做。

从第 106 页开始

// Example 15-1: Lies and Forgery
//
class X {
    // instead of including x.h, manually (and illegally) duplicates X's
    // definition, and adds a line such as:
    friend ::Hijack( X& );
};

void Hijack( X& x ) {
    x.private_ = 2;
}

注意如何在 Hijack 中访问 X 类的私有成员“private_”。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-22
    • 1970-01-01
    • 2013-01-09
    • 2020-01-19
    • 2013-05-23
    • 1970-01-01
    相关资源
    最近更新 更多