2

除了使用“周围类”的引用之外,在 C++ 中是否可以修改“包围”类 B(在“上”范围内)的类 A 的成员?

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

目标是GFullScreen使用与全屏变量相同的值来修改变量。我知道我可以传递GFullScreen整个 Game 类的指针或引用。还有其他方法可以访问它吗?哪个更有效率?

4

6 回答 6

2

不,它会严重破坏封装。无论如何,引用都需要存储在某个地方,隐式或显式 - 你怎么能记住这种关系?

于 2012-01-27T09:31:29.953 回答
2

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.

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.

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:

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.

于 2012-01-27T09:37:03.947 回答
1

是的。请注意,嵌套联合至少需要 1 个字节长,因此需要给 strcpy 一个偏移量。此外,该程序的行为是依赖于实现的,并且更多的是出于演示目的的破解,尽管在实践中我希望它可以与任何现代 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;
};

我的观点是,借助 C/C++ 内部知识,您可以设计一些通常有用且必要的依赖于平台的技巧。然而,这不是,所以我强烈建议不要实际使用上面给出的代码来完成常见任务。

于 2012-01-27T09:53:29.793 回答
1

如果类 B 是在类 A 中定义的,则不能使用类 B 的引用访问类 A 的成员。只有在类 B 是从类 A 继承的情况下才能执行此操作。在这种情况下,使用类型 B 的引用,您将能够访问 A 的公共和受保护成员。

于 2012-01-27T09:33:29.053 回答
0

Unlike Java (nonstatic) inner classes, C++ inner classes doesn't provide any hidden reference to outer class instance (C++ rarely does something hidden, except of vtable), so you need to provide such a reference by yourself, if needed.

于 2012-01-27T09:47:53.610 回答
0

所以我看到没有人用最佳实践示例回答这个问题,我将在这里给出一个:

#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();
}

您将看到您需要自己将上下文传递给包含的类才能访问包含的类。除了自己将上下文传递给类之外,别无他法。

于 2016-07-13T22:59:27.673 回答