C++ 这段代码为什么要编译?

C++ 这段代码为什么要编译?,c++,C++,确定嵌套到其他对象的私有部分中的对象的访问权限的确切规则是什么 例如,在下面截取的代码中,proxy\u t结构嵌套在abc\u t的私有部分中,但其方法可用于main函数。为什么它要编译呢 #include <iostream> #include <valarray> using namespace std; class abc_t{ private: struct proxy_t{ proxy_t operator()(double&am

确定嵌套到其他对象的私有部分中的对象的访问权限的确切规则是什么

例如,在下面截取的代码中,
proxy\u t
结构嵌套在
abc\u t
的私有部分中,但其方法可用于
main
函数。为什么它要编译呢

#include <iostream>
#include <valarray>

using namespace std;

class abc_t{
  private: 
    struct proxy_t{
      proxy_t operator()(double& a, double& b){ __a=a; __b=b; return *this; }
      double a(){ return __a; }
      double b(){ return __b; }
      private:
        double __a, __b;
    };

  public:
    abc_t( const size_t N ){ 
       _a.resize(N,-101.); 
       _b.resize(N,-202.);  
    }
    double a(size_t j){ return _a[j]; }
    double b(size_t j){ return _b[j]; }

    proxy_t operator[](const size_t j) { return _proxy(_a[j],_b[j]); }

  private:
    valarray<double> _a;
    valarray<double> _b;
    proxy_t _proxy;
};


int main(){
 size_t n_elem=10;
 abc_t abc(n_elem);
 cout<<"direct: "<< abc.a(1)<<"  "<<abc.b(1)<<"\n";
 cout<<"proxied:"<<abc[1].a()<<"  "<<abc[1].b()<<"\n";  // ain't proxy_t::aa() private?
 //cout<<abc[1]; // doomed to fail
}
#包括
#包括
使用名称空间std;
abc类{
私人:
结构代理{
proxy_t操作符()(double&a,double&b){{uu_a=a;u_b=b;返回*this;}
双a(){return\uU a;}
双b()
私人:
双a,双b;
};
公众:
abc_t(常数大小N){
_a、 调整大小(N,-101.);
_b、 调整大小(N,-202.);
}
双a(size_t j){return_a[j];}
双b(size_t j){return_b[j];}
proxy_t操作符[](const size_t j){return_proxy(_a[j],_b[j])}
私人:
瓦拉;
瓦卢布;
代理权;
};
int main(){
尺寸n元素=10;
abc_t abc(n元素);

cout这句话是我要说的重要一句话:

cout<<"proxied:"<<abc[1].a()<<"  "<<abc[1].b()<<"\n";
它会崩溃,因为正在声明proxy\t,您正在初始化一个新对象,但是该类型在该范围内不存在。由于您没有实际声明该类型的任何变量,因此在该范围内没有创建任何proxy\t(这将是非法的)

由于代理是私有的,这仅仅意味着除了在abc类中之外,您不能在任何地方创建该类型的任何对象。但是,它被作为返回值传递,这是有效的——没有对象被创建/实例化/声明,只有一个现有的对象被传递

然后是有趣的部分。对于类,默认情况下所有内容都是私有的(除非另有规定)。对于结构,默认情况下所有内容都是公共的。因此,proxy\t::a()是公共的,因此可以在main中使用,因为main恰好可以访问proxy\t对象。

您说的是abc[1]。a()表示转到此处:

proxy_t operator[](const size_t j) { return _proxy(_a[j],_b[j]); }
这是公共的,把1扔给j,然后它返回

_proxy(_a[j],_b[j]) 

调用用于访问a()的私有结构函数

您已将结构代理定义为private,但它公开的实际方法是public。我猜您的编译器不允许您在main中直接实例化代理结构,但如果您从类abc\u t返回一个,它将允许您对其调用public方法


也许知道C++标准的人可以注释这是否是编译器的正确行为。

< p>因为<代码> PROXYOT是一个私有成员,<代码> AbcGyt < /Cube >,除了代码> AccGyt 以外,没有人可以使用它(即这种类型的实例化对象)。但是,给定现有的
代理
,每个人都可以调用其成员,因为它们是公共的

这里的标准有点单调(或者我看错了地方),但这是我最好的发现(11.8):

嵌套类是成员,因此具有与任何其他成员相同的访问权限 封闭类对嵌套类的成员没有特殊的访问权限;通常的访问规则(第11条) 必须服从


字里行间的阅读:由于嵌套类“只是”一个成员,因此当有人引用此类型时(即拼写出
proxy\t
)。但是对于访问
proxy\t
本身的成员,没有特殊的访问规则适用-如果您设法从特权源获取
proxy\t
对象,您可以像访问嵌套类一样访问其成员。

gnu、intel、pgi、Visual Studio Express 2010 C++不知道,但使用双下划线是非法的。“如果你说下面的话,它会崩溃”。你一定是说它不会编译。@Neowizard+1谢谢!修复了。@arasmussen:让我困惑的是:天真地说,我希望abc[1].a()相当于在main()函数中使用_proxy.a()方法,而后者显然是非法的。@Zhenya:因为abc[1]返回一个proxy\u t,并且您没有实例化proxy\u t类型的任何内容,这是合法的。您只是不能实例化任何“proxy\u t”类型的内容"在这个范围内。在你的情况下,你不是,你只是在对其他地方存在的对象调用一个公共方法。@Zhenya-这很像一个函数,返回对类的私有数据的引用。一旦类给你访问权,你就可以使用它,但你自己不能访问它。让我困惑的是:天真地说,我希望abc[1] .a()相当于在main()函数中使用_proxy.a()方法,后者显然是非法的。此外,如果proxy_t只是abc_t的一个成员,那么它是一个私有的。它的成员为什么会被公开?
_proxy(_a[j],_b[j])