2012-11-09 358 views
0

可能重复:
Can inner classes access private variables?
Inner class accessing outer classC++内部类不能访问外部类的成员

我有嵌套,使他们能够有没有额外的输入变量相互作用的一些简单的类,但我的编译器给我一个错误。我如何允许它们在不使用&时间作为函数输入或具有变量&时间在Vect类中进行交互?

我试过使用相同的逻辑,您可以在代码中访问数据,但只能在函数原型的相同位置访问,而不是包装在类中。这适用于我除了其他类以外的任何事情。谁能解释为什么?

我已经标记了使用有问题时间变量的地方,并在定义之前使用了注释行。

/*********/ 
#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; 
} 
+0

你的编译器给你_what_错误? –

+0

为什么嵌套类? –

+0

看看这个:http://stackoverflow.com/questions/486099/can-inner-classes-access-private-variables –

回答

2

你得到一个错误的原因(我设法弄清楚,即使你没有张贴实际的错误,请不要在未来),是你居然没有一个实例Container类里面的Vect类的功能。你或许应该思考的设计在这里,但要迅速解决它(“脏”),你可以添加它设置一个Container例如在子类中的函数:

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; 
}; 

我仍然认为这是怎样的一个肮脏的解决方案的(但不是脏我的第一个),而且你应该考虑改变设计。

+0

我试图避免使用额外的数据访问调用,但我想这是我不能避免,所以我会为它写一个访问函数。谢谢您的帮助! –

+0

@JoeKessler可能更适合嵌套类来保存父对象的引用,并在其构造函数初始化列表中初始化它,因为嵌套类没有父类没有意义。 – juanchopanza

+0

@JoeKessler增加了如何使用juanchopanza的想法。它更干净,更“脏”。 –

0

大部分基本上,类是对等的类。在OOP原则中,每个类都被封装。那么内部类如何直接访问另一个类的成员。它违反了OOP的基本原则。

2

“...嵌套类的成员对封闭类的成员以及对封闭类授予友谊的类或函数没有特殊访问权限;应遵守通常的访问规则(第11章) 。封闭类的成员对嵌套类的成员没有特殊访问权限;应遵守通常的访问规则(第11章)......“

因此,让他们成为朋友。

1

内部类无法访问外部类的非静态变量。这是C++,我们必须在使用它的非静态成员数据之前实例化对象。所以如果你想使用你的设计,你有两种选择:

  1. 改变变量(你的情况下的时间)为静态。但是,对于所有Container类,您只有一个时间副本。

  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; 
    };