C ++で、「周囲のクラス」の参照を使用する以外に、クラスBを「囲む」(「上位」スコープにある)クラスAのメンバーを変更することは可能ですか?
コードはこちら: http://pastebin.com/iEEu9iZG
目標はGFullScreen
、フルスクリーン変数と同じ値で変数を変更することです。Game クラス全体のポインタまたは参照を渡すことができることを知っていGFullScreen
ます.それにアクセスする別の方法はありますか? どちらがより効率的ですか?
C ++で、「周囲のクラス」の参照を使用する以外に、クラスBを「囲む」(「上位」スコープにある)クラスAのメンバーを変更することは可能ですか?
コードはこちら: http://pastebin.com/iEEu9iZG
目標はGFullScreen
、フルスクリーン変数と同じ値で変数を変更することです。Game クラス全体のポインタまたは参照を渡すことができることを知っていGFullScreen
ます.それにアクセスする別の方法はありますか? どちらがより効率的ですか?
いいえ。カプセル化がひどく壊れていたでしょう。とにかく、暗黙的または明示的に参照をどこかに保存する必要がありました-他にどのようにこの関係を思い出すことができますか?
メンバーがstatic
and public
の場合 (または、変数にアクセスするB
メンバー関数がof の場合)、はい。B
friend
A
それ以外の場合は、いいえ。
その理由は、B には A との is-a 関係がないためです。したがって、オブジェクト (参照またはポインター) が必要であるか、アクセスしようとするものはすべて である必要がありますstatic
。
編集:
楽しみのために、B に A との has-a 関係を与えることで、これが可能であるかのように見せることができます。
class A
{
int a;
public:
struct B;
};
class A::B : private A
{
void foo() { A::a = 1; }
};
しかし、もちろん、私はここでごまかしています... これが機能するのは、すべてが a を持っているためです (そしてそのためだけに) B
、A
一度に表示されないだけです。
クラス B がクラス A 内で定義されている場合、クラス B の参照を使用してクラス A のメンバーにアクセスすることはできません。これは、クラス B がクラス A から継承されている場合にのみ可能です。その場合、型 B の参照を使用すると、次のようになります。 A の public および protected メンバーにアクセスできます。
はい。ネストされた共用体は少なくとも 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++ の内部構造の知識があれば、しばしば便利で必要な、プラットフォームに依存するいくつかのハックを考案できるということです。ただし、これはそうではないため、上記のコードを実際に使用して一般的なタスクを実行することは強くお勧めしません。
Java (非静的) 内部クラスとは異なり、C++ 内部クラスは外部クラス インスタンスへの隠し参照を提供しません (C++ は、vtable を除いて、隠し参照を行うことはめったにありません)。そのため、必要に応じて、そのような参照を自分で提供する必要があります。