C++ 有什么方法可以访问类的私有成员变量吗?

C++ 有什么方法可以访问类的私有成员变量吗?,c++,C++,有什么方法可以访问类的私有成员变量吗 编辑: 不是从成员函数或朋友函数而是通过实例。是的,为什么不通过成员函数 C++的“脏窍门”之一是做一些类似的事情: #define private public #include "ClassHeader.h" // now all the private members of the included class are public 我强烈建议您不要这样做。您可以: 将私人成员放置在公共部分 使您的类或函数成为该类的朋友 提供数据的访问器 获取类

有什么方法可以访问类的私有成员变量吗

编辑:
不是从成员函数或朋友函数而是通过实例。

是的,为什么不通过成员函数

C++的“脏窍门”之一是做一些类似的事情:

#define private public
#include "ClassHeader.h"

// now all the private members of the included class are public
我强烈建议您不要这样做。

您可以:

  • 将私人成员放置在公共部分
  • 使您的类或函数成为该类的朋友
  • 提供数据的访问器
  • 获取类的地址,将偏移量添加到该变量、强制转换和取消引用。(恶心)

  • 你想干什么?如果事情是私人的,不要弄乱它。这是私人的,是有原因的。您可以访问私人成员:

    • …在相同(确切)类型的其他实例中
    • …在声明为该类朋友的类或函数中
    • …通过公共访问器(getter/setter)成员函数

    虽然我们提出了一些不好的想法,但代码端并没有强制封装的东西——这完全是一种编译器技巧——因此您可以编写程序集来直接访问私有成员

    但是,如果基类没有完成您想要的任务,为什么不重写它呢?

    为什么要这样做

    可见性规则很明确:

    • 私有方法只能由类的方法访问
    • 受保护的方法可以由类或子类的方法访问
    • 任何人都可以访问公共方法
    。。。因此,如果您自己编写类,请选择正确的可见性。如果它是一个提供的类,那么首先要小心为什么它是私有的

    但是,如果您决定违反该规则,您有几个选择:

    • 您可以通过
      friend
      说明符与应该访问私有方法的类交朋友
    • 你可以使用一个丑陋的预处理器黑客,可能已经有人发布过了,但是如果你需要使用字段或方法进行单元测试,那么你只需要这样做,任何其他的使用都是糟糕的设计
    • 你可以使用一个丑陋的类型铸造黑客,但它是如此丑陋,我甚至害怕张贴它不被否决;>
    只需把它抛来抛去,转移记忆,然后再抛回去。(虽然没有编译代码,但你应该明白这一点)

    Bla类
    {
    公众:
    Bla():x(15),str(“Bla”){}
    私人:
    int x;
    std::字符串str;
    }
    int main()
    {
    布拉布拉;
    int x=*((int*)(&bla));
    std::string str=*((std::string*)((int*)(&bla)+1));
    
    std::cout有关于如何做这些事情的引人入胜的语言律师细节。:-

    我认为这取决于问题的措辞:

    问:如何访问私有成员变量? 我不会的

    以及:

    问:您将如何实施。。。 答:我不会,它已经完成了,我会利用现有的框架/库


    采访者并不总是想知道你是否能做一个轮子,有时他们正在探索,看看你是否知道如何找到最近的服务站。))虽然你增加了免责声明,但有些事情不应该被泄露出去。这使得疯狂的人做起来太容易了。C++标准的第174.3.1.1节:“这样的翻译单元也不能为词汇上与关键字相同的名称定义宏。”当然,没有已知的编译器会拒绝这样的程序。即使是允许这样做的编译器,这也违反了ODR,并导致未定义的行为-P@Michael一旦这些疯子暴露出来,我们就能给他们提供他们需要的药物#定义常数“。这是一个面试问题。我想不出任何办法,除了用指针操作做一些编辑技巧。获取对象的地址,变量的偏移量,然后打印出来。但我不确定我能得到的变量的偏移量是否正确。这个要求你滥用编译器的雇主是谁?正确的答案是“不要”。您可以声明一个friend类来执行此操作,但这样做的设计非常糟糕。为什么他们会询问面试问题,询问如何执行他们应该向您射击的操作?以测试您对编译器内部工作方式的了解,这通常是一件重要的事情。匿名怯懦的否决票?可能是OP。他似乎否决了所有正确的投票t回答:“不要。”这个模板技巧非常棒,但是需要类有一些模板化的东西。@Chris,ehh,如果你引用GotW的话就不能打败你:>IMHO,第四个是最好的:)我在阅读你的答案时想起了这个故事,优化器可以重新安排私有成员的分配顺序,所以这不能保证有效虚拟表指针依赖于实现(标准甚至不要求存在虚拟表指针,尽管每个人都这样做),如果存在公共或受保护的成员,则允许编译器在某种程度上扰乱变量顺序。
    class Bla
    {
    public:
        Bla() : x(15), str("bla") {}
    private:
        int x;
        std::string str;
    }
    
    int main()
    {
        Bla bla;
    
        int x = *((int*)(&bla));
        std::string str = *((std::string*)((int*)(&bla) + 1));
    
        std::cout << x << str;
    
        return 0;
    }