C++ 指向类私有数据成员的指针

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3174763/
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 12:14:25  来源:igfitidea点击:

Pointer to private data member of a class

c++

提问by user382499

Is it possible to declare a pointer to private data member of a class? If so, how do you do it?

是否可以声明指向类私有数据成员的指针?如果是这样,你怎么做?

回答by Tyler McHenry

Yes, and the same way you would create any other pointer. The catch is, of course, that since the member is private, you can only create the pointer insidethe class, where you can see the member.

是的,与创建任何其他指针的方式相同。当然,问题在于,由于成员是私有的,您只能在类内部创建指针,在那里您可以看到该成员。

class A 
{
  public:
    int* getFooPtr()
    {
       return &foo;  // OK; Inside the class foo is visible
    }

  private:
    int foo;
};

int main()
{
   A a;

   int* p_foo1 = &a.foo; // Illegal; Outside the class, foo is private
   int* p_foo2 = a.getFooPtr(); // OK; getFooPtr() is a public member function
}

So it's possible to create pointers to private members, but only inside the class' member functions, and it is possible to return those created pointers from member functions. Whether or not it's a good idea to return pointers to private members is another question entirely (usually it's not a good idea).

所以可以创建指向私有成员的指针,但只能在类的成员函数内部,并且可以从成员函数返回那些创建的指针。返回指向私有成员的指针是否是一个好主意完全是另一个问题(通常这不是一个好主意)。

回答by Gabor Marton

You can access outside of the declaring class any non-static private member if you are exploiting the fact that C++ allows you to pass the address of the private member in explicit instantiation. However you won't be able to access static private members, since you have to use a pointer to member with this technique.

如果您正在利用 C++ 允许您在显式实例化中传递私有成员的地址这一事实,则您可以在声明类之外访问任何非静态私有成员。但是,您将无法访问静态私有成员,因为您必须通过此技术使用指向成员的指针。

struct A
{
     A() : x("proof!") {}
private:
     char const* x;
};

template class stow_private<A_x,&A::x>;

int main()
{
        A a;

        // Use the stowed private member pointer
        std::cout << a.*stowed<A_x>::value << std::endl;
};

You can find the implementation of stowed<>and details here: http://bloglitb.blogspot.hu/2010/07/access-to-private-members-thats-easy.htmland https://gist.github.com/dabrahams/1528856

你可以在stowed<>这里找到实现和细节:http: //bloglitb.blogspot.hu/2010/07/access-to-private-members-thats-easy.htmlhttps://gist.github.com/dabrahams/ 1528856

回答by Brian Hooper

Yes, it is possible, as the previous answers have demonstrated. But as Tyler McHenry asks, "Is it a good idea?". No, it isn't. The member variables are declared private for a good reason, and subverting the encapsulation in this way will only lead to trouble.

是的,这是可能的,正如前面的答案所证明的那样。但正如 Tyler McHenry 所问的,“这是个好主意吗?”。不,不是。成员变量被声明为私有是有原因的,这样颠覆封装只会带来麻烦。

回答by Brian R. Bondy

Yes it's possible. You'd have to return the pointer (or reference) from within the context of the class though, or someone who has friendaccess to the class. That is because the variable itself is private and so can't be accessed otherwise.

是的,这是可能的。您必须从类的上下文中返回指针(或引用),或者从有权friend访问该类的人。那是因为变量本身是私有的,因此不能以其他方式访问。

class C
{
public:
    int* getXPointer()
    {
        return &x;
    }

    int& getXReference()
    {
        return x;
    }

private:
    int x;
};


int main(int argc, char* argv[])
{
    C c;
    int* p = c.getXPointer();
    int& r = c.getXReference();
    assert(p == &r);
    return 0;
}

回答by AnT

The wording of your question is rather confusing. When someone says "declare a pointer to something", they are usually talking about type-related attributes of a pointer, as in "declare a pointer to int". The property of being private does not affect the type of a member at all, meaning that a member of type intis always just a member of type int, regardless of whether it is public or private. This immediately means that a pointer of type int *can always be made to point to a public member of type int, or to a private member of type int. It doesn't matter at all whether the member is public or private.

你的问题的措辞相当混乱。当有人说“声明一个指向某物的指针”时,他们通常是在谈论指针的类型相关属性,如“声明一个指向int”的指针。私有的属性根本不影响成员的类型,这意味着 typeint的成员始终只是 type 的成员int,无论它是公共的还是私有的。这立即意味着int *总是可以使type 指针指向 type的公共成员int或type的私有成员int。成员是公开的还是私有的根本无关紧要。

Another ambiguity in the wording is that in C++ there are ordinary pointers (like int *) and there are pointers of "pointer-to-member" type (like int MyClass::*). When you say "a pointer to data member of a class", it is not clear what kind of pointer you are talking about: ordinary or pointer-to-member. However, the above still applies to both kinds: both can easily point to public, protected or private members of the class. Privateness makes no difference.

措辞中的另一个歧义是,在 C++ 中有普通指针(如int *)和“成员指针”类型的指针(如int MyClass::*)。当您说“指向类数据成员的指针”时,不清楚您在谈论哪种指针:普通指针还是成员指针。但是,以上仍然适用于这两种类型:两者都可以轻松指向类的公共、受保护或私有成员。隐私没有区别。

Again, the property of being "private" does not affect the type of the member, it only affects its accessibility when referred directly, by name. So, in order to make your pointer to point to a private data member of a class you have to initialize that pointer (or assign to it) in an area where that private data member is accessible: inside a method of the owning class or inside a friend function.

同样,“私有”的属性不会影响成员的类型,它只会在直接通过名称引用时影响其可访问性。因此,为了使您的指针指向类的私有数据成员,您必须在该私有数据成员可访问的区域中初始化该指针(或分配给它):在拥有类的方法内部或内部朋友函数。

回答by xil3

Yeah, if I understand you right, you'd like to be able to return a pointer to a private member of a class?

是的,如果我理解正确,您希望能够返回指向类私有成员的指针吗?

private:
        int hidden;
    public:
        int& unHide ()
        {
            return hidden;
        }