1

重複の可能性:
内部クラスはプライベート変数にアクセスできますか?
外部クラスにアクセスする内部クラス

いくつかの単純なクラスをネストして、追加の入力なしで変数と対話できるようにしていますが、コンパイラでエラーが発生します。&time を関数入力として使用したり、変数 &time を Vect クラス内に持たせたりせずに、どうすれば対話できるようになりますか?

関数プロトタイプと同じ場所で、コード内にあるデータにアクセスできるのと同じロジックを使用してみましたが、代わりにクラスにラップされています。これは、他のクラスを除いて、私が使用したものすべてに対してうまく機能します。誰でも理由を説明できますか?

問題のある time 変数を使用する場所を、define の前のようなコメント行でマークしました。

/*********/
#define MAX_POLY 3

class Container
{
public:
    Container(void);
    ~Container(void);

    float time;/*********/
    class Vect
    {
        float P[MAX_POLY],iT;
    public:
        Vect(void){iT = 0.0f;P = {0,0,0};}
        ~Vect(void);

        float GetPoly(int n){return P[n];}
        float Render(void)
        {
            float t = time - iT;/*********/
            float temp[2] = {0,0};
            for(int n=0;n<MAX_POLY;n++)
            {
                temp[0] = P[n];
                for(int m=0;m<n;m++)
                    temp[0] *= t;
                temp[1] += temp[0];
            }
            return temp[1];
        }
        void SetPoly(int n,float f)
        {
            float t = time-iT;/*********/
            P[0] = P[2]*t*t + P[1]*t + P[0];
            P[1] = 2*P[2]*t + P[1];
            //P[2] = P[2];
            P[n] = f;
            iT = time;/*********/
        }
    }X;
};

int main()
{
    Container Shell;
    Shell.X.SetPoly(0,5);
    Shell.X.SetPoly(1,10);
    Shell.X.SetPoly(2,-1);
    for(int n=0;n<10;n++)
    {
        Shell.time = (float)n;
        cout << n << " " << Shell.X.Render() << endl;
    }
    system("pause");
    return 0;
}
4

4 に答える 4

4

エラーが発生する理由 (実際のエラーを投稿していなくても、私はそれを理解することができました。将来的にはそうしてください) は、実際には、の関数内にクラスのインスタンスがないためです。クラス。おそらくここで設計について考える必要がありますが、それをすばやく (そして「汚い」) 解決するには、サブクラスにインスタンスを設定する関数を追加できます。ContainerVectContainer

class Container
{
    ...

    class Vect
    {
        Container *container;

    public:
        void SetContainer(Container &container)
            { this->container = &container; }

        float Render(void)
            {
                float T = container->time - iT;
                ...
            }

        ...
    } X;
};

int main()
{
    Container Shell;
    Shell.X.SetContainer(Shell);
    Shell.X.SetPoly(0,5);
    ...
}

編集:より良い方法は、コンストラクタを使用して親オブジェクトへの参照を設定することです(アイデアについてはjuanchopanzaに感謝します):

class Container
{
    ...

    Container()
        : X(*this)
        { ... }

    class Vect
    {
        Container& container;

    public:
        Vect(Container& cont)
            : container(cont)
            { }

        float Render(void)
            {
                float T = container.time - iT;
                ...
            }

        ...
    } X;
};

私はまだそれが一種の汚い解決策だと思います(ただし、私の最初のソリューションほど汚いわけではありません)。代わりに、デザインを変更することを検討する必要があります。

于 2012-11-09T07:20:16.493 に答える
2

内部クラスは、外部クラスの非静的変数にアクセスできません。これは C++ であり、非静的メンバー データを使用する前にオブジェクトをインスタンス化する必要があります。したがって、自分のデザインを使用する場合は、次の 2 つの選択肢があります。

  1. 変数(あなたの場合は時間)を静的に変更します。ただし、すべての Container クラスに対して time のコピーは 1 つしかありません。

  2. ネストされたクラスに、親クラスへのポインターを含めます。次のコードは Joachim のソリューションに似ていますが、親を明示的に設定する必要はありません。

class Container {

    public:
      Container() : X(this) {}
      float time;

      class Vect {
      public:
        Vect(Container* parent) : parent_(parent) {}
        void foo() {
          myT = parent->time;
        }
      private:
        Container * parent_;
      } X;
    };
于 2012-11-09T07:37:29.607 に答える
2

「...ネストされたクラスのメンバーは、囲んでいるクラスのメンバーへの特別なアクセスも、囲んでいるクラスに友情を与えたクラスまたは関数への特別なアクセスもありません。通常のアクセス規則 (第 11 節) に従うものとします。囲んでいるクラスは、ネストされたクラスのメンバーへの特別なアクセス権を持っていません; 通常のアクセス規則 (第 11 節) に従う必要があります。..."

したがって、彼らを友達にしてください。

于 2012-11-09T07:31:33.740 に答える
0

最も基本的には、クラスはピアツークラスです。OOP の原則では、各クラスはカプセル化されます。したがって、内部クラスが別のクラスのメンバーに直接アクセスする方法。OOP の基本原則に違反しています。

于 2012-11-09T07:27:13.627 に答える