【问题标题】:Way to set private variable of class having more than one member variable设置具有多个成员变量的类的私有变量的方法
【发布时间】:2016-12-21 17:44:21
【问题描述】:

我们可以像this这样设置类的私有变量

我试图为以下情况设置私有成员变量 int。

#include <iostream>
#include <string>

using namespace std;

class Test
{
private:
    string s;
    int data;
public:
    Test() : s("New") , data(0) { }
    int getData() { return data; }
};

int main()
{
    Test t;
    int* ptr = (int*)&t;
    *(ptr+sizeof(string)) = 10;
    cout << t.getData();
    return 0;
}

但它无法打印 10。

我知道还有其他方法可以使用 setter 函数进行设置,但正在检查使用显示的方法进行设置 here

这纯粹是 hack,虽然不是有效的学习方式。

【问题讨论】:

  • 逗号不是 C++ 中的语句分隔符。也许您正在寻找分号?还要考虑一个成员初始化列表。此外,您在main 中使用的代码很危险且已损坏。你为什么要这样做?
  • fairly dangerous 尝试使用指针和偏移量分配给对象中的特定字段,我不会依赖于一般情况下的工作。
  • @CodyGray 看起来他们在main 中所做的破解是一种尝试使用(错误地)假设的对象内存布局分配给private 成员的解决方法
  • @Swapnil 你只是有未定义的行为,所以询问这些东西是徒劳的。
  • 如果有人在采访中问你这种问题,一个合理的反应是说“谢谢”然后走开。你不想在那里工作。

标签: c++ class private-members


【解决方案1】:

我认为这会解决它:

char* ptr = (char*)&t;
*(int*)(ptr+sizeof(string)) = 10;

sizeof 将以字节为单位返回大小。指针增量将用于其指向的对象的大小。 char 是一个字节大小。

如果你想阅读它:C pointer arithmetic article

重申一下我认为你所说的:你只是在学习,你知道在现实生活中你永远不应该这样做......!!

【讨论】:

  • 不,除了忽略任何可能的填充外,这违反了the strict aliasing rule 并且是未定义的行为。
  • @AndrewHenle char* 没有例外吗?
  • @Muscampester 它被转换回int *,然后被取消引用。
  • @AndrewHenle 是的,但该地址的数据是int(或者至少应该是如果我们忽略填充问题)。所以我很想知道这里是否违反了严格的别名规则。
  • @Muscampester 鉴于对齐限制驱动填充,我会说这是准确的。
【解决方案2】:

为什么它不起作用

真的只是永远不要写这样的代码。有一种方法可以设置私有数据,那就是通过类上的公共成员。否则,出于某种原因,它是私有的。这是 C++,实际上有非 UB 方法可以做到这一点,但我不会在这里链接它们,因为没有。

为什么它不起作用,特别是

提示:ptr + sizeof(string) 实际上是什么意思,因为ptrint*?这行后面的ptr 指的是什么?

【讨论】:

    【解决方案3】:

    指针运算应该使用字节指针,而不是整数指针。

    #include <iostream>
    #include <string>
    
    using namespace std;
    
    class Test
    {
    private:
        string s;
        int data;
    public:
        Test() { s = "New", data = 0; }
        int getData() { return data; }
    };
    
    int main()
    {
       Test t;
       char* ptr = (char*)&t;
       *(int*)(ptr+sizeof(string)) = 10;
       cout << t.getData();
       return 0;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-02-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多