访问私人会员

Shr*_*ree 8 c++ private-members

通过将类转换为void指针然后转换为结构来访问类的私有成员是否合适?

我认为我没有权限修改包含我需要访问的数据成员的类.如果不符合道德规范,我不想以间接方式冒险访问数据成员.

编辑:不得不进一步编辑...我很确定这个类不会被修改,所以它可以在那个程度上...我唯一关心的是,如果编写该类的人知道这一点,它可能跟他没关系:(.

Dav*_*ley 26

我们暂时不要考虑道德问题.让我们考虑标准.

你提议做的是非标准的.见标准第9.2节第9.2节."未指定由访问说明符分隔的非静态成员的分配顺序." 因此,如果您有一个具有私有成员的类,以及一个没有私有成员的结构,则该标准不保证成员的顺序相同.

因此,如果你的黑客工作,它只是偶然的,编译器编写者碰巧这样做.无法保证它可以在另一个编译器,同一编译器的更高版本或不同的类布局上工作.

更不用说,如果您没有权限修改类(例如,提供简单的访问器函数),如果类中的任何实现细节发生更改,您可能无权对象.(公共和私人背后的一个想法是区分承诺与可自由变更的内容.)因此,布局可能会发生变化,或者成员可能意味着不同的东西,或者完全被删除.

Herb Sutter 在这个问题上写了一个本周的大师专栏.

哦,就道德而言呢?如果你真的,真的必须做这样的事情,而你无法摆脱它,请非常仔细地记录下来.如果您的编码标准有某种程序来标记非标准行为,请使用它们.如果没有,请小心注意,当出现问题时不会被忽视.


Jon*_*eet 25

我不确定"道德"真的会进入它.尽管如此,它还是破坏了封装.

编辑:如果我进行代码审查,我几乎不会接受这个.你必须非常努力地说服我,没有办法围绕这个需求进行设计.你可能会成功,但是必须在整个地方发出重大警告,并进行坚硬的单元测试以确保如果有任何改变可以打破它,你很快就会知道.


Joh*_*itb 16

我刚刚在我的博客中添加了一个条目,展示了如何以完全一致的方式完成它.以下是如何将其用于以下类的示例

struct A {
private:
  int member;
};
Run Code Online (Sandbox Code Playgroud)

只需声明一个标签名称并实例化一个强盗,如下面的示例所示(我的帖子显示了强盗的实施).然后,您可以使用成员指针访问该成员

struct Amem { typedef int type; };
template class rob<Amem, &A::member>;

int main() {
  A a;
  a.*result<Amem>::ptr = 42; // Doh!
}
Run Code Online (Sandbox Code Playgroud)

但实际上,这并没有表明c ++的访问规则不可靠.语言规则旨在防止意外错误 - 如果您尝试抢夺对象的数据,则设计语言不会花费很长时间来阻止您.


以上是一种以符合标准的方式访问私有和受保护成员的方法.这是以标准符合方式访问受保护成员的另一种方法.基本思想是使用成员指针

std::deque<int> &getAdapted(std::stack<int> &s) {
    struct voyeur : stack<int> 
    { using stack<int>::c; };
    return s.*(&voyeur::c);
}

int main() {
    std::stack<int> s;
    std::deque<int> &adapted = getAdapted(s);
    output(adapted); // print the stack...
}
Run Code Online (Sandbox Code Playgroud)

不涉及铸造或类型惩罚.它std::stack<int>通过从其派生的类获取受保护成员的指针,其中该成员名称是公共的,因此编译器允许这样做.然后它在一个std::stack<int>对象上使用它,这也是允许的.


Joh*_*ing 7

不,你在做什么是Pure Evil.


Jer*_*rks 7

我遇到过这种情况,因为有一个非常糟糕的源代码控制系统,旧版本的应用程序对头文件进行更改几乎是不可能的.

如果有些情况你只需要做一个黑客攻击.

在您需要访问私有数据成员的源文件中,您可以将其作为第一行放入:

#define private public
#define protected public
Run Code Online (Sandbox Code Playgroud)

并访问你想要的任何东西.


Dou*_* T. 5

"永远不要把话说绝了".我确信在宇宙的某个地方,有一种情况迫使你不得不这样做......

但如果我不得不这样做,我当然会畏缩.在扣动扳机之前,你真的需要对你的情况有很多意见.你能描述一下你的具体情况吗?也许我们可以看看它是否有意义或者可能存在哪些更好的选择?

回应评论/问题 - 定义"权限" - 机构许可?这听起来不是一个编程问题,但可以与任何主张上述许可的人交谈.也许这更像是一个政治问题而不是技术问题?同样,我认为我们需要更具体的内容 - 即使它在某种程度上与情况的政治有关.但是,这可能会或可能不会被视为超出网站的范围.

  • 扔掉那个类并使用一个提供访问该成员的类. (2认同)