基本和派生定义如下:
class Base {
public:
virtual int f1(int a) const = 0;
virtual int f2(int a, int b) const { return a+b;}
};
class Derived : public Base {
public:
int f1(int a) const { return a; }
};
int main() {
Derived obj;
cout << obj.f1(1) << endl;
cout << obj.f2(1, 2) << endl;
}
结果是
1
3
obj.f1(1)使用来自 Derived 和 obj.f2(1、2)的 f1 实现使用从 Base 继承的实现,这就是我想要的。
现在,我希望这两个函数具有相同的名称 f ,因此,当有两个参数且派生类必须实现单个参数版本时,基类将提供一个实现(即为什么它是纯虚拟的。)
但是,如果我这样做(只需将 f1 和 f2 重命名为 f ):
class Base {
public:
virtual int f(int a) const = 0;
virtual int f(int a, int b) const { return a + b;}
};
class Derived : public Base {
public:
int f(int a) const { return a; }
};
int main() {
Derived obj;
cout << obj.f(1) << endl;
cout << obj.f(1, 2) << endl;
}
我收到以下错误:
20:23: error: no matching function for call to 'Derived::f(int, int)'
20:23: note: candidate is:
14:13: note: virtual int Derived::f(int) const
14:13: note: candidate expects 1 argument, 2 provided
这是为什么?这种重载不可能吗?
答案 0 :(得分:10)
您需要写
class Derived : public Base {
public:
using Base::f;
int f(int a) const { return a; }
};
请注意using
语句。这将基类版本带回了范围。
答案 1 :(得分:8)
现在,我希望这两个函数具有相同的名称
f
您需要写
class Derived : public Base {
public:
using Base::f;
int f(int a) const { return a; }
};
请注意using
语句。这将基类版本带回了范围。 [感谢@Bathsheba]
这是为什么?这种重载不可能吗?
否,由于[basic.scope.hiding¶3],不能像原始问题中所述那样写:
在成员函数定义中,在块处声明名称 范围隐藏具有相同成员的类的声明 名称;参见[basic.scope.class]。 成员的声明 派生类隐藏该类的基类成员的声明 相同的名称; 请参见[class.member.lookup]。
此子句与名称有关,而不是重载。因此,基类中是否有其他重载也没关系,它们都共享相同的名称 ,根据上面的引用将其隐藏。
答案 2 :(得分:1)
您可以通过编写Sub testarr()
Dim arr As Variant, str As String, i As Integer
str = "{test:[{test this here||Can it be split inside the array?}]}"
arr = Split(str, "[{")
For i = LBound(arr) To UBound(arr)
arr(i) = Split(arr(i), "||")
Next i
End Sub
将Base的所有定义纳入范围,也可以为f的某些版本专门编写如下内容:using Base::f;
int f(int a, int b) const override {return Base::f(a,b);}
在answer中已经提到了using的版本:
class Derived : public Base {
public:
int f(int a) const { return a; }
int f(int a, int b) const override {return Base::f(a,b);}
};
注意:我知道第二个版本在MSVC 2010上不起作用。我也知道此编译器是古老的,但仅适用于关心的人;)
答案 3 :(得分:0)
除了其他解决方案之外,如果您不想重新定义f
,则可以使用
f
int main() {
Derived obj;
cout << obj.f1(1) << endl;
cout << obj.Base::f2(1, 2) << endl;
}
答案 4 :(得分:-2)
您还可以使它们全部纯净,然后在派生类中覆盖它们。您可以继续使用自己的课程。