Ale*_*son 23 c++ operator-precedence pointer-to-member
您好我有这个代码与编译器错误(错误来自Microsoft Visual Studio 2008):
class B
{
protected:
int b;
};
class A : public B
{
public:
void foo(){ &B::b; }// error C2248: 'B::b' : cannot access protected member declared in class 'B'
};
Run Code Online (Sandbox Code Playgroud)
虽然此代码没有错误:
class B
{
protected:
int b;
};
class A : public B
{
public:
void foo(){ &(B::b); }
};
Run Code Online (Sandbox Code Playgroud)
基于我对运算符优先级的了解,这两个片段在我看来是等价的,因为::具有比&更高的优先级(例如参见"联合攻击战斗机车辆C++编码系统开发和编码标准"第137页的表2)演示计划" http://www2.research.att.com/~bs/JSF-AV-rules.pdf)
但它们是不同的...我认为它与"指向数据成员"有关,但我不知道它如何与运算符优先级相符.
任何解释?
谢谢,亚历山德罗
Mar*_*k B 13
在第一种情况下,您将获取指向成员的地址B::b.由于这样的指针不是父节点的成员A而是单独的对象,因此它无法通过受保护机制访问它.
在它的工作原理你要求的地址第二种情况下的具体实例的b,与它的基类限定它,这样在多重继承的情况下,编译器会知道你的意思,其基类.在此上下文中,受保护的属性是可见的.
请注意,这编译:
class B
{
protected:
int b;
};
class A : public B
{
public:
void foo(){ &A::b; } // Note here &A:: instead of &B::
};
Run Code Online (Sandbox Code Playgroud)
作为一个附加示例,它不起作用的原因与以下(希望更熟悉)代码不起作用的原因相同:
class B
{
protected:
int b;
};
class A : public B
{
public:
void foo(const B* b_obj) { b_obj->b; }
};
Run Code Online (Sandbox Code Playgroud)
这只是补充.
§5.3.1/ 2说:
一元&运算符的结果是指向其操作数的指针.操作数应为左值或限定ID.在第一种情况下,如果表达式的类型是"T",则结果的类型是"指向T的指针"...
对于qualified-id,...如果成员是非静态成员类型为T的类C,结果的类型是"指向类型T的C类成员的指针".
根据§5.1/ 7,B::b属于qual -id案件,但(B::b)没有.因此,编译器将其解释为左值.
当您尝试返回值时,两个语句之间的差异变得更加明显:
int* foo() { return &(B::b);} // This is a pointer to an int
int A::* foo() { return &B::b; } // This is a pointer to a member of type int
Run Code Online (Sandbox Code Playgroud)
你想要做的是通过A对象访问它:
int A::* foo() { return &A::b; } // This is a pointer to a member of type int
Run Code Online (Sandbox Code Playgroud)
从A开始,您可以访问它.
通过B访问它就是从外部访问它,从而触发访问说明符.