C++ 如何在不结交“朋友”的情况下访问类外的私有数据成员?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6717163/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 20:34:41  来源:igfitidea点击:

How to access private data members outside the class without making "friend"s?

c++classprivateencapsulationdata-members

提问by Abhineet

I have a class Aas mentioned below:-

我有一个class A如下所述:-

class A{
     int iData;
};

I neither want to create member function nor inherit the above class Anor change the specifier of iData.

我既不想创建成员函数,也不想继承上述内容,class A也不想更改iData.

My doubts:-

我的疑问:-

  • How to access iDataof an object say obj1which is an instance of class A?
  • How to change or manipulate the iDataof an object obj1?
  • 如何访问iData一个对象说obj1哪个是 的实例class A
  • 如何更改或操作iData对象的obj1

Note: Don't use friend.

注意:不要使用friend.

采纳答案by Mat

You can't. That member is private, it's not visible outside the class. That's the whole point of the public/protected/private modifiers.

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

(You could probably use dirty pointer tricks though, but my guess is that you'd enter undefined behavior territory pretty fast.)

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

回答by Sleiman Jneidi

Here's a way, not recommended though

这是一种方法,虽然不推荐

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 = "Hyman";
    cout << w.getName() << endl;

}

回答by Alok Save



EDIT:
Just saw you edited the question to say that you don't want to use friend.
Then the answer is:

编辑:
刚刚看到您编辑了问题,说您不想使用朋友。
那么答案是:

NO you can't, atleast not in a portable way approved by the C++ standard.

不,你不能,至少不能以 C++ 标准批准的可移植方式。



The later part of the Answer, was previous to the Q edit & I leave it here for benefit of >those who would want to understand a few concepts & not just looking an Answer to the >Question.

答案的后面部分在 Q 编辑之前,我将它留在这里是为了让那些想要了解一些概念的人受益,而不仅仅是寻找问题的答案。



If you have members under a Private access specifier then those members are only accessible from within the class. No outside Access is allowed.

如果您在 Private 访问说明符下有成员,那么这些成员只能从类内部访问。不允许外部访问。

An Source Code Example:

源代码示例:

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
}

A Workaround: friendto rescue
To access the private member, you can declare a function/class as friend of that particular class, and then the member will be accessible inside that function or class object without access specifier check.

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

Modified Code Sample:

修改后的代码示例:

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;
}

回答by Ajay

Bad idea, don't do it ever - but here it is how it can be done:

坏主意,永远不要这样做 - 但这是如何做到的:

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

   ptr = (int*)&aObj;

   // MODIFY!
   *ptr = 100;
}

回答by Timmah

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

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

this guy's blog shows you how to do it using templates. With some modifications, you can adapt this method to access a private data member, although I found it tricky despite having 10+ years experience.

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

I wanted to point out like everyone else, that there is an extremely few number of cases where doing this is legitimate. However, I want to point out one: I was writing unit tests for a software suite. A federal regulatory agency requires every single line of codeto be exercised and tested, withoutmodifying the original code. Due to (IMHO) poor design, a static constant was in the 'private' section, but I needed to use it in the unit test. So the method seemed to me like the best way to do it.

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

I'm sure the way could be simplified, and I'm sure there are other ways. I'm not posting this for the OP, since it's been 5 months, but hopefully this will be useful to some future googler.

我相信方法可以简化,我相信还有其他方法。我不是为 OP 发布这个,因为它已经 5 个月了,但希望这对未来的一些谷歌人有用。

回答by Alexander Drichel

In C++, almost everything is possible! If you have no way to get private data, then you have to hack. Do it only for testing!

在 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;
}

回答by RocketR

There's no legitimate way you can do it.

没有合法的方法可以做到这一点。

回答by n. 'pronouns' m.

iDatais a privatemember of the class. Now, the word privatehave a very definite meaning, in C++ as well as in real life. It means you can't touch it. It's not a recommendation, it's the law. If you don't change the class declaration, you are not allowed to manipulate that member in any way, shape or form.

iDataprivate班级的成员。现在,这个词private在 C++ 和现实生活中都有非常明确的含义。这意味着你不能碰它。这不是建议,这是法律。如果不更改类声明,则不允许以任何方式、形状或形式操纵该成员。

回答by iammilind

Start making friends of class A. e.g.

开始做friendclass A。例如

void foo ();

class A{
  int iData;
  friend void foo ();
};

Edit:

编辑

If you can't change class Abody then A::iDatais not accessible with the given conditions in your question.

如果您无法更改class A正文,则A::iData无法使用问题中的给定条件访问。

回答by James

friendis your friend.

朋友是你的朋友。

class A{
    friend void foo(A arg);
    int iData;
};

void foo(A arg){
     // can access a.iData here
}

If you're doing this regularly you should probably reconsider your design though.

如果你经常这样做,你可能应该重新考虑你的设计。