c ++使用声明,范围和访问控制

has*_*stk 11 c++ scope access-control using-declaration

通常,'using'声明用于将基本类的一些成员函数纳入范围,否则这些函数将被隐藏.从这个角度来看,它只是一种使可访问信息更便于使用的机制.
但是:'using'声明也可用于更改访问约束(不仅用于函数,还用于属性).例如:

class C{
public:
  int a;
  void g(){ cout << "C:g()\n"; }
  C() : a(0){}
};

class D : public C{
private:
  using C::a;
  using C::g;
public:
  D() { a = 1; }
};

int main(void){
  D d;
  cout << d.a << endl;  //error: a is inaccessible
  C *cp = &d;
  cout << cp->a << endl; //works
  d.g();  //error: g is inaccessible
  cp->g();  //works
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

我认为派生类中的访问限制实际上没有用,因为你总是可以从指向基类的指针访问g()和a.那么至少应该有某种编译器警告吗?或者禁止衍生类的访问限制更好?使用声明不是添加约束以进行访问的唯一可能性.它也可以通过覆盖基类的函数并将其放在具有更多访问限制的部分中来完成.是否有一些合理的例子,以这种方式限制访问确实是不可取的?如果不是,我不明白为什么应该允许它.

还有一件事:至少使用g ++,相同的代码编译得很好而没有"使用"这个词.这意味着对于上面的例子:可以编写C :: a; 和C :: g; 而不是使用C :: a; 使用C :: g; 第一个只是后者的捷径还是有一些微妙的差异?

//编辑:
所以从下面的讨论和答案我得出的结论是:
- 允许使用公共继承来限制派生类中的访问约束
- 有一些有用的示例可以使用
它 - 它的使用可能会导致与模板结合的问题(例如,派生类不能再作为某个模板类/函数的有效参数,尽管它的基础是)
- 更干净的语言设计不应允许这样的使用
- 编译器至少可以发出某种警告

Joh*_*itb 5

关于你的声明没有using:这些被称为"访问声明",并且已被弃用.以下是标准中的文字,来自11.3/1:

通过在派生类声明中提及其qualified-id,可以在派生类中更改基类成员的访问权限.这种提及称为访问声明.访问声明的效果被定义为等同于声明[脚注:不推荐访问声明; 成员使用声明(7.3.3)提供了一种更好的方法来做同样的事情.在早期版本的C++语言中,访问声明更加有限; 它们被概括并等同于使用声明 - 结束脚注]qualified-id;usingqualified-id;

我会说,最常见的是将派对类中的公共成员更改为私有成员或受保护成员是不好的,因为这会违反替换原则:您知道基类具有某些功能,如果您转换为派生类,那么您期望这些函数也可以调用,因为派生类是一个基类.就像你已经提到的那样,这个不变量已经被语言允许转换(隐式地工作!)到基类引用,或者限定函数名,然后调用(然后是public)函数.

如果你想禁止有人调用基类的一组函数,那么我认为这暗示遏制(或在极少数情况下,私有继承)是一个更好的主意.