如何在没有"朋友"的情况下访问课外的私人数据成员?

Abh*_*eet 15 c++ encapsulation private class data-members

我有class A如下所述: -

class A{
     int iData;
};
Run Code Online (Sandbox Code Playgroud)

我既不想创建成员函数也不继承上面的内容,class A也不想更改说明符iData.

我的疑惑: -

  • 如何访问iData一个对象说obj1哪个是实例class A
  • 如何更改或操纵iData对象obj1

注意:请勿使用friend.

Sle*_*idi 22

这是一种方式,但不推荐

class Weak {
private:
    string name;

public:
    void setName(const string& name) {
        this->name = name;
    }

    string getName()const {
        return this->name;
    }

};

struct Hacker {
    string name;
};

int main(int argc, char** argv) {

    Weak w;
    w.setName("Jon");
    cout << w.getName() << endl;
    Hacker *hackit = reinterpret_cast<Hacker *>(&w);
    hackit->name = "Jack";
    cout << w.getName() << endl;

}
Run Code Online (Sandbox Code Playgroud)

  • 注意 - 如果类有一个 vtable (`std::is_polymorphic&lt;T&gt;()`),您需要声明一个额外的 `void *` 作为第一个成员。不用说,这是一个肮脏的黑客之上的另一个肮脏的黑客 - 避免这样做。 (5认同)

Alo*_*ave 10


编辑:
刚刚看到你编辑了问题,说你不想使用朋友.
然后答案是:

不,你不能,至少不是以C++标准批准的便携方式.


答案的后半部分是在Q编辑之前,我把它留在这里是为了那些想要理解一些概念并且不仅仅是对问题的答案.


如果您拥有私有访问说明符下的成员,则只能从类中访问这些成员.不允许外部访问.

源代码示例:

class MyClass
{
    private:
        int c;
    public:
    void doSomething()
    {
        c = 10;    //Allowed 
    }
};

int main()
{
    MyClass obj;
    obj.c = 30;     //Not Allowed, gives compiler error
    obj.doSomething();  //Allowed
}
Run Code Online (Sandbox Code Playgroud)

解决方法:friend要进行抢救
要访问私有成员,可以将函数/类声明为该特定类的朋友,然后可以在该函数或类对象中访问该成员而无需访问说明符检查.

修改代码示例:

class MyClass
{
    private:
        int c;

    public:
    void doSomething()
    {
        c = 10;    //Allowed 
    }

    friend void MytrustedFriend();    
};

void MytrustedFriend()
{
        MyClass obj;
        obj.c = 10; //Allowed
}

int main()
{
    MyClass obj;
    obj.c = 30;     //Not Allowed, gives compiler error
    obj.doSomething();  //Allowed
    //Call the friend function
    MytrustedFriend();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)


Mat*_*Mat 9

你不能.该成员是私人的,在课堂外不可见.这是public/protected/private修饰符的重点.

(你可能会使用脏指针技巧,但我的猜测是你很快就会进入未定义的行为领域.)

  • 问题是:"请注意:我不想使用朋友". (4认同)
  • [朋友](http://en.wikipedia.org/wiki/Friend_function)[朋友](http://en.wikipedia.org/wiki/Friend_class)...我的朋友:) (3认同)
  • @Mat我想你在技术上是正确的,但我认为他们的意思是不将“friend”添加到你想要访问的类中。没有理由人为地限制课外活动。 (2认同)

Aja*_*jay 9

不好的想法,不要永远这样做 - 但在这里它是如何做到的:

int main()
{
   A aObj;
   int* ptr;

   ptr = (int*)&aObj;

   // MODIFY!
   *ptr = 100;
}
Run Code Online (Sandbox Code Playgroud)

  • 绝对!从其他类继承,更改pragma,添加虚函数,使其成为联合 - 我没有说它是正确的! (3认同)
  • 这可能导致未定义的行为.不便携. (2认同)

Tim*_*mah 7

http://bloglitb.blogspot.com/2010/07/access-to-private-members-thats-easy.html

这个人的博客向您展示了如何使用模板来做到这一点.通过一些修改,您可以调整此方法来访问私有数据成员,尽管我发现它很棘手,尽管有10年以上的经验.

我想像其他人一样指出,只有极少数情况下这样做是合法的.但是,我想指出一个:我正在为软件套件编写单元测试.联邦监管机构要求在修改原始代码的情况下行使和测试每一行代码.由于(恕我直言)设计不佳,静态常量在"私人"部分,但我需要在单元测试中使用它.所以这种方法在我看来是最好的方法.

我确信这种方式可以简化,我确信还有其他方法.我不是为OP发布这个,因为它已经有5个月了,但希望这对未来的一些googler有用.


Ale*_*hel 5

在 C++ 中,几乎一切皆有可能!如果你无法获取私人数据,那么你就必须进行黑客攻击。仅用于测试!

class A {
     int iData;
};

int main ()
{
    A a;
    struct ATwin { int pubData; }; // define a twin class with public members
    reinterpret_cast<ATwin*>( &a )->pubData = 42; // set or get value

    return 0;
}
Run Code Online (Sandbox Code Playgroud)