除了使用“周围类”的引用之外,在 C++ 中是否可以修改“包围”类 B(在“上”范围内)的类 A 的成员?
代码在这里: http: //pastebin.com/iEEu9iZG
目标是GFullScreen
使用与全屏变量相同的值来修改变量。我知道我可以传递GFullScreen
整个 Game 类的指针或引用。还有其他方法可以访问它吗?哪个更有效率?
除了使用“周围类”的引用之外,在 C++ 中是否可以修改“包围”类 B(在“上”范围内)的类 A 的成员?
代码在这里: http: //pastebin.com/iEEu9iZG
目标是GFullScreen
使用与全屏变量相同的值来修改变量。我知道我可以传递GFullScreen
整个 Game 类的指针或引用。还有其他方法可以访问它吗?哪个更有效率?
不,它会严重破坏封装。无论如何,引用都需要存储在某个地方,隐式或显式 - 你怎么能记住这种关系?
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.
是的。请注意,嵌套联合至少需要 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++ 内部知识,您可以设计一些通常有用且必要的依赖于平台的技巧。然而,这不是,所以我强烈建议不要实际使用上面给出的代码来完成常见任务。
如果类 B 是在类 A 中定义的,则不能使用类 B 的引用访问类 A 的成员。只有在类 B 是从类 A 继承的情况下才能执行此操作。在这种情况下,使用类型 B 的引用,您将能够访问 A 的公共和受保护成员。
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.
所以我看到没有人用最佳实践示例回答这个问题,我将在这里给出一个:
#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();
}
您将看到您需要自己将上下文传递给包含的类才能访问包含的类。除了自己将上下文传递给类之外,别无他法。