简体   繁体   English

c ++:访问包含希望访问的类的类的成员

[英]c++: Access to members of a class that contains the class that wants the access

Is it possible in c++ to modify a member of a class A that "surrounds" the class B (is in the "upper" scope) besides using a reference of the "surrounding class"? 除了使用“环绕类”的引用之外,在c ++中是否可以修改“包围”类B的类A的成员(在“上”范围内)?

code is here: http://pastebin.com/iEEu9iZG 代码在这里: http : //pastebin.com/iEEu9iZG

The goal is to modify the GFullScreen variable with the same value of the fullscreen variable. 目标是使用与全屏变量相同的值修改GFullScreen变量。 I know that I can pass a pointer of GFullScreen or a reference of the whole Game class.. Is there another way to access to it? 我知道我可以传递GFullScreen的指针或整个Game类的引用。是否有另一种访问方法? which one is more efficient? 哪个更有效?

No. It would have broken encapsulation horribly. 不。它会严重破坏封装。 And reference would have needed to be stored somewhere anyway, implicitly or explicitly - how else could you remember this relation? 而且无论如何,都必须隐式或显式地将引用存储在某个地方-您还怎么会记住这种关系?

If the member is static and public (or if B or the member function in B accessing the variable is a friend of A ), then yes. 如果成员是static 且是 public (或者BB访问变量的成员函数是Afriend ),则为是。

In every other case, no. 在其他情况下,不可以。

The reason is that B does not have an is-a relation to A, thus you need either an object (reference or pointer), or whatever you try to access must be static . 原因是B与A没有is-a关系,因此您需要一个对象(引用或指针),或者您尝试访问的任何对象都必须是static

EDIT: 编辑:
Just for fun, it is possible to make it look as if this was possible, by giving B a has-a relationship to A: 只是为了好玩,可以通过给B与A一个has-a关系,使它看起来像是可能的:

class A
{
    int a;

public:
    struct B;
};

class A::B : private A
{
    void foo() { A::a = 1; }
};

But of course I'm cheating here... this works because (and only because) every B has-a A , you only don't see it at once. 但是,我当然在这里作弊...之所以奏效,是因为(并且仅因为)每个B都有A ,您不会一次看到它。

如果在类A中定义了类B,则不能使用类B的引用访问类A的成员。只有在类B继承自类A的情况下,您才能这样做。在这种情况下,使用类型B的引用,您将能够访问A的公共成员和受保护成员。

Yes. 是。 Note that the nested union is required to be at least 1 byte long, so an offset needs to be given to strcpy. 请注意,嵌套联合的长度至少应为1个字节,因此需要为strcpy提供一个偏移量。 Also, the behavior of this program is implementation-dependent and is more of a hack for demonstration purposes, though in practice I'd expect it to work predictably with any modern C++ compiler. 此外,该程序的行为与实现有关,并且更多是用于演示目的,尽管在实践中我希望它可以与任何现代C ++编译器一起正常工作。

#include <cstring>
#include <iostream>

struct _a
{
        union _b {
                void mutate()
                {
                        strcpy(reinterpret_cast<char*>(this) + 1, "Goodbye, World!");
                }
        } b;
        char buf[256];

        _a() { strcpy(buf, "Hello, World!"); }
} a;

int main()
{
        std::cout << a.buf << "\n";
        a.b.mutate();
        std::cout << a.buf << std::endl;
        return 0;
};

My point is that with knowledge of C/C++ internals, you can devise some platform-dependent hacks that are often useful and necessary. 我的观点是,借助C / C ++内部知识,您可以设计一些经常有用且必要的依赖于平台的黑客。 This one isn't however, so I'd highly advise against actually using the code given above to accomplish common tasks. 但是,这不是,因此我强烈建议您不要实际使用上面给出的代码来完成常见任务。

So I see no one has answered this with a best practice example, I will give one here: 因此,我认为没有人用最佳实践示例回答这个问题,在这里我将举一个:

#include <iostream>
using namespace std;

//before includes:
class A;

//B.h
class B{
    public:
        B(A *);
        void test();
        A *parent;
};

//A.h
class A{
    public:
        A();
        ~A();

        B *b;
        void test();

        int n;
};

//B.cpp
B::B(A *a){
    parent = a;
}

void B::test(){
    cout << parent->n;
}

//A.cpp
A::A(){
    n = 404;
    b = new B(this);
}
A::~A(){
    delete b;
}
void A::test(){
    b->test();
}

//example.cpp
int main( int argc, char **argv){
    A a;
    a.test();
}

You will see that you need to pass the context yourself to the contained class to access the containing class. 您将看到需要将上下文自己传递给包含的类以访问包含的类。 There is no other way, than by passing the context yourself to the class. 除了通过将上下文自己传递给类之外,没有其他方法。

与Java(非静态)内部类不同,C ++内部类不提供对外部类实例的任何隐藏引用(C ++除了vtable很少提供隐藏的东西),因此,如果需要,您需要自己提供这样的引用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM