我一直在高低寻找我认为是一个相当简单的问题的答案:为什么拒绝访问声明?
class A
{
public:
int testInt;
}
class B: public A
{
private:
A::testInt;
}
据我所知,只需在A::testInt
前面“使用”即可解决问题。
但是如果没有某种理解,为什么我必须这样做,这感觉就像一个廉价的解决方案。
更糟糕的是,它使我对使用声明/指令和范围解析运算符的理解变得混乱。如果我必须在这里使用使用声明,为什么我能在其他地方使用SRO和SRO?一个简单的例子是std::cout
。为什么不使用std::cout
?我曾经认为使用和SRO或多或少可以互换(给予或采用“using”关键字提供的一些方便的功能,我知道,至少在名称空间的情况下)。
我在标准中看到了以下内容:
通过在派生类声明中提及>其qualified-id,可以在派生类中更改对基类成员的访问。这种提及称为访问>声明。访问声明qual-id的效果;被定义为与使用qualified-id的声明等效>; [脚注:访问声明已被弃用; member> using-declarations(7.3.3)提供了一种更好的方法来做同样的事情。在早期版本的C ++语言中,访问声明更加有限;它们被概括为>并且等同于使用声明 - 结束脚注]
然而,除了确认我已经知道的事情外,这除了真的没什么用。如果你真的把它煮熟了,我相信我的问题源于我认为使用和SRO可以互换的事实,但我没有看到任何暗示的东西。
提前致谢!
答案 0 :(得分:3)
如果我必须在这里使用使用声明,为什么我能在其他地方使用SRO和SRO?
咦?你无法做到。不要在不同的范围内重新声明名称(这是访问声明所做的)。
一个简单的例子是std :: cout。为什么不使用std :: cout?
因为它们不是一回事,甚至不是很接近。
一个引用名称,另一个引用名称。
我确信我的问题源于我认为使用和SRO可以互换的事实
我同意这是你的问题,因为你完全错了。使用声明之后,没有必要对名称进行限定,但这并不能使它们互换。
std::cout
是一个表达式,它引用变量,因此您可以写入它,将其作为函数参数传递,获取其地址等。
using std::cout;
是一个声明。它使名称cout
在当前范围内可用,作为名称std::cout
的别名。
std::cout << "This is an expression involving std::cout\n";
using std::cout; // re-declaration of `cout` in current scope
如果您建议保持一致性,则应执行此操作以写信至cout
:
using std::cout << "This is madness.\n";
那么,呃,那太疯狂了。
在课堂上,当您想要重新声明具有不同访问权限的成员时,您将重新声明,因此您需要声明。你不是试图引用要写入的对象来将它包含在某个表达式中,如果它在类范围内被允许,它将如下所示:
class B: public A
{
private:
A::testInt + 1;
};
为了与语言的其余部分保持一致,使用using-declaration
重新声明基类中的名称,因为这是一个声明,它不是用看起来像表达式的东西完成的。
class B: public A
{
private:
A::testInt; // looks like an expression involving A::testInt, but isn't
using A::testInt; // re-declaration of `testInt` in current scope
};
将此与上面的std::cout
示例进行比较,您将看到要求using
完全一致,并且从C ++中删除访问声明会使语言更加一致。