有没有一种不太直截了当的方法将基类方法引入子类?
Is there a less blunt way of bring base class methods into a child class?
>考虑
struct Base
{
int foo(int);
int foo(int, int);
};
struct Child : Base
{
using Base::foo;
int foo(int, int, int);
};
理想情况下,我想将仅接受一个int
作为参数的Base
类foo
引入Child
类,而不是需要 2int
s 的类。有没有办法做到这一点?我的写作using Base::foo;
带来了两种foo
Base
方法。
using 声明将使所有重载可用。你无法阻止这种情况的发生。但是你可以在事后delete
你不想要的重载:
struct Base
{
int foo(int);
int foo(int, int);
};
struct Child : Base
{
using Base::foo;
int foo(int, int) = delete;
int foo(int, int, int);
};
现在,将两个 int 重载与Child
一起使用是格式不正确的。然而,这不是一个完美的解决方案,因为客户端仍然可以调用基本版本:
Child c;
c.Base::foo(0, 0);
无法将指定的重载函数引入派生类。名称查找规则处理名称,但重载函数具有相同的名称foo
。
您可以在派生类中编写包装器函数,例如
struct Child : Base
{
int foo(int x) { return Base::foo(x); }
int foo(int, int, int);
};
我将列出其他答案中提出的两种解决方案,并详细说明它们的不同之处。
struct Child : Base
{
int foo(int x) { return Base::foo(x); }
int foo(int, int, int) { std::cout << 3; return 33; }
};
这完全符合您的要求,但您必须重复签名。
略有不同的结果是:
struct Child : Base
{
using Base::foo;
int foo(int,int)=delete;
int foo(int, int, int) { std::cout << 3; return 314; }
};
要了解这有何不同,请假设我们这样做了:
struct Grandkid : Child
{
using Child::foo;
int foo(double, double) { std::cout << 2; return 42; }
};
我们做到了:
Grandkid x;
x.foo(3,4);
在=delete
的情况下,这将生成编译器错误。
3,4
更喜欢int,int
而不是double,double
。 当我们=delete
int,int
重载时,它仍然被考虑、选择,我们选择=delete
d。 当我们将其从过载分辨率中排除时,3,4
会选择double,double
。
手动转发排除了int,int
过载。=delete
没有。
这最类似于using Base::foo(int);
的虚构语法(即,只引入foo
的一个父重载)。
请注意,Grandkid
只是检测差异的一种简单方法。 重要的是,从过载解决中删除某些内容与=delete
重载之间存在差异。
现场示例在哪里有效,在哪里无效。
相关文章:
- C++:在派生类成员上调用基类方法
- 在基类方法中调用不同类的方法
- 无法访问派生类中的基类方法
- 有没有办法禁止派生类中的基类方法调用?
- 给定基类方法的编译时重写
- 在派生类中调用基类方法,而无需指定基类名称
- 如何将基类方法超载作为参数传递到C 中的模板类
- 如何模拟调用其基类方法的派生类
- 当应该调用派生类方法时,为什么要调用基类方法
- 从基类方法返回对派生类的引用
- 无法从派生的一个方法调用基类方法
- 用受保护的继承指向基类方法
- 使用来自基类方法的派生类数据成员
- 传递指针或引用派生类,以便调用基类方法
- C++11可变参数模板方法完全影子基类方法
- 更改基类方法在其派生类中的返回类型
- std::异步不能调用受保护的基类方法
- 是否有希望在std::变体上高效地调用一个公共基类方法
- 有没有一种不太直截了当的方法将基类方法引入子类?
- 重新定义派生类中的基类方法