回答:
内部クラスは、内部で定義されているクラスのフレンドです。
あ、はい; タイプのオブジェクトは、タイプのオブジェクトのOuter::Inner
メンバー変数var
にアクセスできますOuter
。
ただし、Javaとは異なり、タイプOuter::Inner
のオブジェクトと親クラスのオブジェクトの間に相関関係はありません。親子関係を手動で作成する必要があります。
#include <string>
#include <iostream>
class Outer
{
class Inner
{
public:
Inner(Outer& x): parent(x) {}
void func()
{
std::string a = "myconst1";
std::cout << parent.var << std::endl;
if (a == MYCONST)
{ std::cout << "string same" << std::endl;
}
else
{ std::cout << "string not same" << std::endl;
}
}
private:
Outer& parent;
};
public:
Outer()
:i(*this)
,var(4)
{}
Outer(Outer& other)
:i(other)
,var(22)
{}
void func()
{
i.func();
}
private:
static const char* const MYCONST;
Inner i;
int var;
};
const char* const Outer::MYCONST = "myconst";
int main()
{
Outer o1;
Outer o2(o1);
o1.func();
o2.func();
}
内部クラスは外部クラスのすべてのメンバーにアクセスできますが、Javaの奇妙な点とは異なり、親クラスインスタンスへの暗黙的な参照はありません。したがって、外部クラスへの参照を内部クラスに渡すと、外部クラスインスタンスのすべてを参照できます。
varは内部クラスのメンバーではありません。
varにアクセスするには、外部クラスインスタンスへのポインタまたは参照を使用する必要があります。たとえば、pOuter-> varは、内部クラスが外部のフレンドである場合、またはC ++標準に厳密に従っている場合、varがパブリックの場合に機能します。
一部のコンパイラは内部クラスを外部のフレンドとして扱いますが、そうでないコンパイラもあります。IBMコンパイラについては、次のドキュメントを参照してください。
「ネストされたクラスは別のクラスのスコープ内で宣言されます。ネストされたクラスの名前は、それを囲むクラスに対してローカルです。明示的なポインター、参照、またはオブジェクト名を使用しない限り、ネストされたクラスの宣言は、型名、静的メンバー、および包含クラスとグローバル変数からの列挙子。
ネストされたクラスのメンバー関数は通常のアクセスルールに従い、それらを含むクラスのメンバーへの特別なアクセス権限はありません。外側のクラスのメンバー関数は、ネストされたクラスのメンバーに特別なアクセス権を持ちません。」
friend
またはを明示的に宣言する必要はありませんpublic
。IBMが過去にデッドリンクで誤解/古くなっていたかどうかは誰が気にかけますか?この回答は、投稿される3年前にすでに古くなっています。
まずvar
、C ++では許可されていない、クラス外の非静的メンバーにアクセスしようとしています。
マークの答えは正しいです。
Outerの一部であるものはすべて、パブリックまたはプライベートのすべてのOuterのメンバーにアクセスできる必要があります。
したがって、外部クラスのインスタンスの宣言var
として宣言するstatic
か、その参照を使用して「var」にアクセスするという2つのことを実行できます(フレンドクラスまたは関数もプライベートデータにアクセスするための参照が必要なため)。
静的変数
クラスのインスタンスに関連付けられないようにするには、に変更var
しstatic
ますvar
。
#include <iostream>
class Outer {
private:
static const char* const MYCONST;
static int var;
public:
class Inner {
public:
Inner() {
Outer::var = 1;
}
void func() ;
};
};
int Outer::var = 0;
void Outer::Inner::func() {
std::cout << "var: "<< Outer::var;
}
int main() {
Outer outer;
Outer::Inner inner;
inner.func();
}
出力変数:1
非静的変数
オブジェクトの参照は、非静的メンバー変数にアクセスする必要があります。
#include <iostream>
class Outer {
private:
static const char* const MYCONST;
int var;
public:
class Inner {
public:
Inner(Outer &outer) {
outer.var = 1;
}
void func(const Outer &outer) ;
};
};
void Outer::Inner::func(const Outer &outer) {
std::cout << "var: "<< outer.var;
}
int main() {
Outer outer;
Outer::Inner inner(outer);
inner.func(outer);
}
出力変数:1
編集-外部リンクは私のブログへのリンクです。