【问题标题】:Why are access declarations deprecated? What does this mean for SRO and using declarations?为什么不推荐使用访问声明?这对 SRO 和使用声明意味着什么?
【发布时间】:2014-04-21 21:16:17
【问题描述】:

我一直在寻找一个我认为相当简单的问题的答案:为什么不推荐使用访问声明?

class A
{
public:
    int testInt;
}

class B: public A
{
private:
   A::testInt;
}

我知道它可以通过简单地在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-declarations - end footnote]

但是,除了确认我已经知道的内容之外,这实际上没有任何作用。如果您真的归结为,我确信我的问题源于我认为 using 和 SRO 可以互换的事实,但我没有看到任何其他建议。

提前致谢!

【问题讨论】:

  • deprecated 究竟是哪个标准版本? c++11?这可能与您的问题非常相关...
  • 这就是我的顽皮表现的地方。回答你的问题:我不确定。我已经看到到处都张贴了那个块引用,所以我只是假设它是普遍正确的,并且随后会适用于我。 stackoverflow.com/questions/2084801/… - 一个例子,如果有帮助的话。我一直在研究 Alex Alllain 的“Jumping into C++”并使用 learncpp.com。除此之外,我知道的不多。我希望这不会让我的问题过于模糊。
  • 我用c++已经很久了,我什至不知道你可以从派生类中改变基类成员的访问级别。
  • @πάνταῥεῖ:有趣的是,第一个 C++ 标准 C++98 中已经弃用了访问声明。
  • @JonathanWakely,除非你永远不应该修复代码。

标签: c++ deprecated language-lawyer


【解决方案1】:

如果我必须在这里使用 using 声明,为什么我可以在其他地方使用 SRO 而只能使用 SRO?

嗯?你不能。不要在不同的范围内重新声明名称(这是访问声明所做的)。

一个简单的例子是 std::cout。为什么不使用 std::cout?

因为它们不是一回事,甚至不接近。

一个引用一个名字,另一个重新声明一个名字。

我确信我的问题源于我认为 using 和 SRO 可以互换

我同意这是你的问题,因为你完全错了。在 using 声明之后,不必限定名称,但这不会使它们可以互换。

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++ 中删除访问声明会使语言更加一致。

【讨论】:

    猜你喜欢
    • 2022-12-12
    • 1970-01-01
    • 2016-05-25
    • 1970-01-01
    • 2014-09-20
    • 2022-12-05
    • 1970-01-01
    相关资源
    最近更新 更多