プロが教えるわが家の防犯対策術!

内部クラスのスコープ、friendクラスのスコープについて詳しいかたお願いします。

以下のクラス構成の場合に、
1.Outerクラスのすべてメンバー関数からはInnerクラスのすべての関数にアクセスできるのでしょうか?

2.InnerクラスからOuter::outerPrivateFunction(); を利用するためにはInnerクラスをOuterクラスのfriendにする方法以外にありますでしょうか?

3.InnerクラスからOuter::outerInt にどのようにしてもアクセスできません。ためした方法はInnerクラスをOuterクラスのfriendにする方法です。
このようなクラス構成にしてしまうと不可能なのでしょうか?

4.friendにしたクラスはprivateの変数、関数にアクセス可能になるはずですが、
それは外部クラスに限ってのことで内部クラスには当てはまらないのでしょうか?

class Outer {
private:
class Inner {
Innerfunction();
Onter* pOuter;
}

outerPrivateFunction();
int outerInt;
}

説明に不足があれば補足いたしますのでお詳しいかた宜しくお願いします。

A 回答 (3件)

 こんばんは。

再投稿です。

 ↓すんません、仕出かしてしまいました。これはNGです。
void outerPrivateFunction()
{
Inner().Innerfunction();
}

 以下問題点・御指摘頂いた点を修正してみました。VC6.0とVC2005でコンパイル、実行もしてあります。
 どうやらOuter::が無くても良い(?)様です。

//friend class Innerを妨害するための独立したInnerクラス
class Inner
{
void Innerfunction(){}

int a;
int b;
};

//本題のクラス
class Outer
{
private:
class Inner;
friend class Inner;

class Inner
{
private:
friend Outer;

public:
explicit Inner(Outer* p) : pOuter(p){}

private:
void Innerfunction()
{
pOuter->outerInt++;
pOuter->outerPrivateFunction();
}

void Innerfunction2(){}

Outer* pOuter;
};

public:
Outer() : inner(this), outerInt(0){}
void outerPublicFunction(){inner.Innerfunction();}

private:
void outerPrivateFunction(){inner.Innerfunction2();}

Innerinner;
intouterInt;
};

 「More C++ Idioms/内部クラス(Inner Class)」
 http://ja.wikibooks.org/wiki/More_C%2B%2B_Idioms …

この回答への補足

>どうやらOuter::が無くても良い(?)様です。
これですが必要ないと思います。
Interクラスの仮定義をOuterクラスの外に出すか、中に書くかで
外部クラス、内部クラスを指定することができるのではないでしょうか。
ですので、上記コードですと、class Innter;(仮定義)をコメントアウトすれば
、妨害するための独立したInnerクラスをfriendにすることができるのではないでしょうか。

補足日時:2008/09/22 23:38
    • good
    • 0
この回答へのお礼

補足ありがとうございます。わざわざ動かしていただいたみたいで。
friend Outer;が少しはまりそうなので覚えておきます。
friend class Outer;としてしまいそうです。

お礼日時:2008/09/22 23:37

Outer側のfriend宣言は


friend class Outer::Inner;
としてやれないといけないでしょう

friend class Inner;
と書いてしまっては
class Outer
{
};

Class Inner
{
};
と独立したクラスだと解釈されるでしょう

Innerfunctionは Outerの参照を引数にとるかInnerクラスのコンストラクタでpOuterを初期化するとかしないとpOuterの初期化ができないように思います

OuterのouterPrivateFunctionやouterIntがprivateならInnerクラスに
friend class Outer;
が無いとエラーになるでしょう
    • good
    • 0
この回答へのお礼

細かいところまでフォローありがとうございます。

お礼日時:2008/09/22 23:27

 こんにちは。



1・はい。Innerクラスのメンバ関数へのアクセス指定をpublicにすれば可能です。

2・はい。ただ、するべき事では無いかと。
 Outerクラスにstaticメンバ関数などを置き、その関数がOuter::outerPrivateFunction()のメンバ関数ポインタを返せば出来ます。
 ただ、メンバ関数ポインタを返す関数は、publicでないと出来ません。

3・friendの書き方が悪かったのかもしれません。

4・可能な筈です。

 以下で通る筈です(余白を空ける為に全角スペースを入れているので要注意)。

 class Outer
 {
 private:
    class Inner;

    friend class Inner;

    class Inner
    {
    public:
        void Innerfunction()
        {
            pOuter->outerPrivateFunction();
            pOuter->outerInt;
        }

    private:
        Outer* pOuter;
    };

    void outerPrivateFunction()
    {
        Inner().Innerfunction();
    }

    int outerInt;
 };
    • good
    • 0
この回答へのお礼

ありがとうございます。
確認したところ、ご指摘どおりfriendの書き方が悪く、
class Innerの仮定義をclass Outerの外に出しておりました。
内部クラスの場合には、内部で定義する必要があるのですね。
とても助かりました。

お礼日時:2008/09/22 23:23

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!