在不显示指针地址的情况下访问指针数据

Posted

技术标签:

【中文标题】在不显示指针地址的情况下访问指针数据【英文标题】:Give Access to a Pointer's Data Without Revealing Pointer Address 【发布时间】:2016-01-13 05:36:15 【问题描述】:

我有一个包含指针的类。我想阻止类的用户访问指针的地址(所以他们不能将它设置为另一个地址,删除它,或者什么不)。但是,我希望用户能够修改指针数据(或成员数据,如果它不是 POD)以及调用指针的方法(假设它有任何方法)。

是否有任何方法可以返回指针或引用,使您可以更改指针指向的 数据 而无法更改 指针值本身?

所以:

class A

public:
    int Value;
    void Method();
;

class Wrapper

public:
    Wrapper()
    
        Pointer = new A;
    
    // Method that somehow would give access to the object without 
    // Allowing the caller to access the actual address
    A* GetPointer()
    
        return Pointer;
    

private:
    A* Pointer;
;

int main()

    Wrapper foo;

    foo.GetPointer()->Value = 12; // Allowed
    foo.GetPointer()->Method();   // Allowed
    A* ptr = foo.GetPointer();    // NOT Allowed
    delete foo.GetPointer();      // NOT Allowed

    return 0;

我意识到我可以使用 getter 和 setter 修改成员数据,但我不确定如何处理这些方法(可能传递一个方法指针?)我想知道在我之前是否有更好的方法接受我个人认为看起来很混乱的解决方案。

【问题讨论】:

嗯,用你提到的 getter 和 setter 修改它是封装私有数据的重点,这听起来像你想要做的......也就是说,允许访问和更新值,但在类中保留和管理对该数据的控制。 确切地说,我只是不确定调用封装对象的方法,是否必须将方法指针传递给内部调用它的函数,或者是否有其他更好的方法. 我想让类的用户不能访问指针的地址 -- 为什么Pointer必须是指针?为什么不将A 对象作为成员?那么delete就没什么了或者改地址了。 我质疑您是否需要允许 foo.GetPointer()->Value = 12; 但不允许 A* ptr = foo.GetPointer();。目前尚不清楚您要保护什么。请记住,坚定的程序员可能会破坏您精心设计的访问控制。 @5gon12eder 我害怕那个。我一直在努力“保护”我的代码,以至于我忘记了 C++ 编码器是 C++ 编码器 因为 他们不是儿童. 【参考方案1】:

这是不可能的。 ->Value 合法的全部原因是左边的表达式是指向 A* 的(智能)指针。

显然,使用非智能指针,您的A* 就在那里。由于原始指针不是用户定义的类型,因此您不能搞乱重载决议。

使用智能指针,(*ptr).Value 必须工作。这意味着您必须从operator* 返回一个A&,这反过来又意味着&(*ptr) 从智能指针中为您获取traw 指针。

对于试图阻止 operator& 的类,甚至还有 std::addressof

【讨论】:

【参考方案2】:

您可以创建一个返回对象引用的 getter,例如:

A &GetObject()

    return *Pointer;

这允许完全访问指向的对象,而根本不提供对指针本身的访问。

【讨论】:

如果我这样做A* foo = &x.GetObject()? 您正在回答问题,但这不是 JubileeTheBear 的意思。通过返回一个引用,你实际上是给调用者一个指针的副本,这样调用者就不能修改所有者的原始指针,但是 JubileeTheBear 想要阻止调用者能够调用delete(你仍然可以这样做指针的副本)。 JubileeTheBear 真正想要的是一种让调用者修改对象而不知道它在内存中的位置的方法,这是不可能的。

以上是关于在不显示指针地址的情况下访问指针数据的主要内容,如果未能解决你的问题,请参考以下文章

如何在构造函数中访问类变量以在不使用 C++ 中的 this 指针的情况下分配它们

在不移动文件指针的情况下检查文件指针是不是已达到 EOF?

有没有办法在不进行查询的情况下读取指针

C++:在不知道函数名的情况下获取当前函数指针?

使用指针在 C++ 中显示 char 变量的地址?

有没有办法在不知道派生类型的情况下将包含派生指针的 std::any 转换为基指针?