gpt4 book ai didi

inheritance - 为什么重载的成员函数只有在 D 中没有被覆盖的情况下才会自动继承?

转载 作者:行者123 更新时间:2023-12-04 03:04:12 27 4
gpt4 key购买 nike

在 D 中,假设我有一个相当于以下示例的案例:

import std.stdio;
import std.conv;

class first{

int func(int x){
return x;
}

int func(double x){
return to!(int)(x+0.5);
}
}

class second : first{
override int func(int x){
return x/2;
}
}


unittest{
second blah = new second();
writeln(blah.func(4.5));
}

请注意,在第一个类中,“func”被重载,第二个类覆盖了采用 int 的 func 版本,而不是采用 double 的版本。

此代码无法编译,并显示一条消息,提示 func(double) 未被继承:
tmp.d(24): Error: function tmp.second.func (int x) is not callable using 
argument types (double)

但是,如果我从“second”类中删除覆盖函数,则继承 func(double) 。这样做之后,代码将按预期编译和运行。

删除对非继承重载函数 tmp.func(4.5) 的调用会产生不同的编译错误:
tmp.d(15): Deprecation: class tmp.second use of tmp.first.func(double x) hidden 
by second is deprecated. Use 'alias first.func func;' to introduce base class
overload set.

似乎建议我应该将 first.func 的别名声明为 func in second,实际上,将该别名添加到“second”类允许代码编译。

尽管这解决了问题,但我对为什么以这种方式实现 D 感到有些困惑。这给我留下了两个问题:

1. 为什么重载的函数如果没有被覆盖会自动继承,而如果其中一个被覆盖则不会?

2. 有没有办法在没有这种别名的情况下只覆盖一个重载的成员函数?

最佳答案

是为了防止函数劫持:http://dlang.org/hijack.html

从历史上看,在 C++ 程序中存在各种有趣的问题,其中您不调用您打算调用的函数,并且通过强制程序员将所有函数的重载显式引入派生类范围,它迫使程序员确保他们期望调用的重载被调用,而不是仅仅因为隐式转换的工作方式而调用基类实现。因此,虽然从表面上看可能有点烦人,但它有助于防止细微的错误。

如果要控制派生类中的重载,则必须单独声明每个重载。如果将基类的重载别名为派生类的范围,则会获得所有重载。从语法上讲,无法告诉编译器您希望使用该特定符号名称为某些函数添加别名。你所能做的就是给出符号名称,所以要么全有要么全无。但是通过在派生类中声明你想要的每个重载(如果你不想改变它们的行为,它们每个都使用 super 调用基类版本),然后你可以控制你拥有哪些。是的,这有点乏味,但不幸的是,事情就是这样。

但是,无论如何,明确地为每个重载设置别名并不是那么冗长。如果它是合法的,它大概是这样的

alias foo = bool X.foo(int a, float b) const;

(其中 X 是基类的名称)而不是
bool foo(int a, float b) const { return super(a, b); }

所以,我不认为添加别名特定重载的能力会给你带来很多好处。

关于inheritance - 为什么重载的成员函数只有在 D 中没有被覆盖的情况下才会自动继承?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25193169/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com