Bra*_*don 2 c++ deprecated language-lawyer
我一直在寻找一个我认为相当简单的问题的答案:为什么访问声明被弃用?
class A
{
public:
int testInt;
}
class B: public A
{
private:
A::testInt;
}
Run Code Online (Sandbox Code Playgroud)
我知道它可以通过简单地在前面加上“using”来修复A::testInt,但如果不了解为什么我必须这样做,这感觉就像一个廉价的修复。
更糟糕的是,它混淆了我对使用声明/指令和范围解析运算符的理解。如果我必须在此处使用 using 声明,为什么我可以在其他地方使用 SRO 而只能使用 SRO?一个简单的例子是std::cout。为什么不使用使用std::cout?我曾经认为 using 和 SRO 或多或少是可以互换的(提供或获取“using”关键字提供的一些方便的功能,我知道这一点,至少在命名空间的情况下)。
我在标准中看到了以下内容:
通过在派生类声明中提及 > 其限定 ID,可以在派生类中更改基类成员的访问权限。这种提及称为访问>声明。访问声明qualified-id的效果;被定义为等同于>使用qualified-id的声明;[脚注:不推荐使用访问声明;member >using-declarations (7.3.3) 提供了更好的方法来做同样的事情。在 C++ 语言的早期版本中,访问声明受到更多限制;它们被泛化>并等同于使用声明 - 结束脚注]
然而,这实际上只是证实了我已经知道的事情。如果你真的把它归结起来,我确信我的问题源于这样一个事实:我认为 using 和 SRO 是可以互换的,但我还没有看到任何其他建议。
提前致谢!
如果我必须在此处使用 using 声明,为什么我可以在其他地方使用 SRO 而只能使用 SRO?
啊?你做不到。不要在不同的范围内重新声明名称(这是访问声明的作用)。
一个简单的例子是 std::cout。为什么不使用 using std::cout ?
因为它们不是同一件事,甚至不相近。
一个指代一个名字,另一个重新声明一个名字。
我确信我的问题源于这样一个事实:我认为 using 和 SRO 是可以互换的
我同意这是你的问题,因为你完全错了。在 using 声明之后,不需要限定名称,但这并不会使它们可以互换。
std::cout是一个表达式,它引用变量,因此您可以对其进行写入、将其作为函数参数传递、获取其地址等。
using std::cout;是一个声明。它使 namecout在当前范围内可用,作为 name 的别名std::cout。
std::cout << "This is an expression involving std::cout\n";
using std::cout; // re-declaration of `cout` in current scope
Run Code Online (Sandbox Code Playgroud)
如果您建议为了保持一致性,您应该这样做以写信给cout:
using std::cout << "This is madness.\n";
Run Code Online (Sandbox Code Playgroud)
那么,呃,这太疯狂了。
在类中,当您想要重新声明具有不同访问权限的成员时,您就是在重新声明它,因此您需要一个声明。您并不是试图引用要写入的对象以将其包含在某些表达式中,该表达式(如果在类范围内允许)将如下所示:
class B: public A
{
private:
A::testInt + 1;
};
Run Code Online (Sandbox Code Playgroud)
为了与语言的其余部分保持一致,从基类重新声明名称是使用 a 完成的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
};
Run Code Online (Sandbox Code Playgroud)
将此与std::cout上面的示例进行比较,您会发现 requireusing是完全一致的,并且从 C++ 中删除访问声明使语言更加一致。