C ++:隐藏规则的基本原理

C ++ 隐藏规则的基本原理是什么?

class A { void f(int); } class B : public A { void f(double); } // B::f(int) is hidden 
  • 如果这是一个有意义的function,我认为也应该可以隐藏函数而不用定义具有相同名称的新函数:像这样的东西:

     class B : public A { hide void f(double); } 

    但这是不可能的。

  • 我不认为这简化了编译器的工作,因为编译器无论如何都必须能够在显式使用using指令时取消隐藏函数:

     class B : public A { using A::f; void f(double); } // B::f(int) NOT hidden 

那么,怎么会有一个隐藏的规则?


嗯,这三个答案看起来都不错,而且对隐藏规则也显示出不同的理由。 我不确定我应该接受哪个答案。

这是一个棘手的问题,但显然这个想法是,这个隐藏function有助于避免在修改基类(否则可能“窃取”之前由派生类处理的调用)时出现细微的错误。 仍然在基类的变化可以影响编译派生类的结果,所以我不认为我理解100%这个解释。

我同意这个话题经常被讨论,可能隐藏实际上增加了C ++程序员“惊喜”的数量。

关于这个问题的详细讨论可以在这里find…

我不知道原来的理由,但是因为藏起来或不藏起来都是差不多的select。 函数,我猜测的基本原理是有统一的规则 :在嵌套的花括号范围内定义的名称相同。

隐藏在某些方面帮助你。

将方法添加到基类将默认不会影响派生类的重载parsing。

而且你不会因为一些不正确的指令而导致你的调用失败,从而void*带有forms参数void*的基类方法。 这样的事情。

干杯&hth。,

我确定我已经看到了这个由C ++大佬提供的情况,不知道是哪个:

 struct Base { void f(const Base&); }; struct Derived : Base { using Base::f; void f(double); }; int main() { Derived d; df('a'); // calls Derived::f } 

现在,添加void f(int);Base ,和主要变化的意义 – 它调用Base::f因为intchar更好的匹配 – 这是一个整数推广,而不是一个标准的转换。

目前还不清楚这种改变是否真的被程序员用char来捕获,所以要求using明确的意思是默认的行为是这个改变不会影响调用代码。 我相信这只是一个边际的呼吁,但我认为委员会认为C ++中的基类已经足够脆弱了,没有这些:-)

没有必要使用“隐藏”关键字,因为在Derived中没有重载“f”的情况下,没有可比性的情况。

顺便说一句,我已经select了types, char故意不协调。 你可以用intunsigned int来获得更微妙的情况,而不是intchar

隐藏基类的成员函数(具有相同名称但签名不同)的另一个原因可能是由可选参数引起的歧义。 考虑下面的例子:

 #include <stdio.h> class A { public: int foo(int a, int b=0) { printf("in A : %d, %d\n", a, b); } }; class B : public A { public: int foo(int a) { printf("in B : %d\n", a); foo(a); //B:foo(a) will be called unless we explicitly call A:foo(a) foo(a, 1); // compile error: no matching function for call to B:foo(int&, int) } }; int main() { B b; b.foo(10); return 0; } 

如果基类中的foo方法没有被隐藏起来,那么编译器就不可能决定是否应该调用A::foo或者是B::foo因为以下代码行与两个签名都匹配:

 foo(a); 

可能的原因是模板专业化。 我举个例子:

 template <int D> struct A { void f() }; template <> struct A<1> { void f(int) }; template <int D> struct B: A<D> { void g() { this->f(); } }; 

模板类B有一个方法f() ,但是直到你不创build类B的实例,你不知道签名。 所以调用this->f()是随时“合法”的 。 在创build实例之前,GCC和CLang都不报告错误。 但是,当您调用B<1>实例的方法g() ,它们会指示错误。 所以隐藏规则保持简单,以检查你的代码是否有效。

我报告在我的例子中使用的代码的最后一部分。

 int main (int argc, char const *argv[]) { B<0> b0; /* valid */ B<1> b1; /* valid */ b0.g(); /* valid */ b1.g(); /* error: no matching function for call to 'B<1>::f()' */ return 0; } 
    Interesting Posts