C++:隐藏规则背后的基本原理
隐藏规则背后的基本原理是什么C++?
class A { void f(int); }
class B : public A { void f(double); } // B::f(int) is hidden
如果这是一个有意义的功能,我认为也应该可以隐藏函数而无需定义具有相同名称的新函数:如下所示:
class B : public A { hide void f(double); }
但这不可能。
我认为它不会简化编译器的工作,因为当您显式使用
using
指令时,编译器必须能够取消隐藏函数:class B : public A { using A::f;无效 f(双精度); } // B::f(int) 不隐藏
那么,为什么会有隐藏规则?
What's the rationale behind the hiding rule in C++?
class A { void f(int); }
class B : public A { void f(double); } // B::f(int) is hidden
If it is a meaningful feature I think it should also be possible to hide functions without defining new functions with the same name: something like this:
class B : public A { hide void f(double); }
but this is not possible.
I don't think it simplifies compilers job, since compilers must anyway be able to unhide functions when you explicitly use the
using
directive:class B : public A { using A::f; void f(double); } // B::f(int) NOT hidden
So, how come there is a hiding rule?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
这是一个棘手的问题,但显然这个想法是,这种隐藏功能有助于避免在更改基类时出现微妙的错误(否则可能会“窃取”之前由派生类处理的调用)。基类的更改仍然会影响派生类的编译结果,所以我认为我不能 100% 理解这个解释。
我同意这个话题被如此频繁地讨论,以至于隐藏实际上可能增加了 C++ 程序员的“惊喜”数量。
有关此问题的详细讨论可以在此处< /a>...
It's an hairy question, but apparently the idea is that this hiding feature helps avoiding subtle bugs when making changes to a base class (that could otherwise "steal" calls that before would have been handled by the derived class). Still a change in a base class can influence the result of compilation of derived classes so I don't think I understand 100% this explanation.
I agree that this topic is so frequently discussed that probably the hiding actually increases the amount of "surprises" in C++ programmers.
A detailed discussion about this issue can be found here...
我不知道最初的理由,但因为隐藏或不隐藏都是同样糟糕的选择。对于函数,我猜其基本原理是具有统一规则:与嵌套大括号范围中定义的名称相同。
隐藏在某些方面对你有帮助。
默认情况下,向基类添加方法不会影响派生类的重载解析。
并且您不会因某些意外将带有参数
false
的调用定向到具有形式参数void*
的基类方法而与重载解析发生冲突。这样的事情。干杯&呵呵,
i don't know the original rationale, but since hide or not hide are about equally bad choices wrt. to functions, i'm guessing the rationale is to have uniform rules: the same as for names defined in nested curly-braces scopes.
the hiding helps you in some ways.
adding a method to a base class will by default not affect overload resolution for a derived class.
and you do not run afoul of overload resolution by some mishap directing your call with say argument
false
, to a base class method with formal argumentvoid*
. such things.cheers & hth.,
我确信我见过 C++ 大佬提供的这个案例,但不确定是哪个:
现在,在
Base
中添加void f(int);
,以及其含义主要变化 - 它调用Base::f
因为int
更适合char
- 它是整数提升而不是标准转换。目前尚不清楚对基址的更改是否真的是程序员有意捕获使用
char
的调用,因此要求using
是显式的意味着默认行为是更改不会影响调用代码。我相信这是一个边际呼吁,但我认为委员会认为 C++ 中的基类本身就足够脆弱,没有这个:-)不需要“隐藏”关键字,因为没有隐藏“f”的类似情况当 Derived 中未重载时,来自 Base。
顺便说一句,我选择了类型,而
char
是故意不协调的。您可以使用int
与unsigned int
而不是int
与char
来获得更微妙的情况。I'm sure I've seen this case offered by a C++ bigwig, not sure which:
Now, add
void f(int);
toBase
, and the meaning of main changes - it callsBase::f
becauseint
is a better match forchar
- it's an integer promotion rather than a standard conversion.It's not clear whether that change to the base would really be intended by the programmer to catch calls with
char
, so requiringusing
to be explicit means the default behavior is that the change doesn't affect the calling code. I believe it's a marginal call, but I think the committee decided that base classes in C++ were fragile enough as they are, without this too :-)There's no need for a "hide" keyword because there's no comparable case for hiding "f" from the Base when it isn't overloaded in Derived.
Btw, I've chosen the types, and
char
is deliberately incongruous. You can get more subtle cases withint
vsunsigned int
rather thanint
vschar
.隐藏基类的成员函数(具有相同名称但不同签名)的另一个原因可能是由于可选参数引起的歧义。考虑下面的例子:
如果基类中的
foo
方法没有被隐藏,编译器就不可能决定是否应该调用A::foo
或B::foo
因为以下行匹配两个签名:Another reason for hiding base class's member function (with same name but different signatures) might be due to ambiguity caused by optional parameters. Consider the following example:
If the
foo
method in base class hadn't become hidden, it wouldn't be possible for compiler to decide whetherA::foo
should be called orB::foo
since the following line matches both signatures:原因可能是模板专业化。我举个例子:
模板类 B 有一个方法
f()
,但是在您不创建类 B 的实例之前,您不知道其签名。因此,调用this->f()
任何时候都是“合法的”。在创建实例之前,GCC 和 CLang 都不会报告错误。但是,当您在B<1>
实例上调用方法g()
时,它们会指示错误。因此,隐藏规则可以更简单地检查您的代码是否有效。我报告了示例中使用的代码的最后一部分。
Probably, the reason is template specialization. I give you an example:
The template class B has a method
f()
, but until you don't create an instance of the class B you don't know the signature. So the callthis->f()
is anytime "legal". Both GCC and CLang don't report error until you create the instance. But when you call the methodg()
on aB<1>
instance they indicate the error. So the hiding rule keep simpler to check if your code is valid.I report the last part of code used in my example.