jpf*_*342 3 c++ inheritance overloading
我有一个看起来像这样的课程:
class A
{
public:
void foo(int arg) { foo(arg, false); }
private:
void foo(int arg, bool flag) {}
};
Run Code Online (Sandbox Code Playgroud)
它是这样构建的,因为我希望foo'flag 参数仅在从外部调用时为 false A。我想私下继承它,但允许调用foo:
class B : private A
{
public:
using A::foo;
};
Run Code Online (Sandbox Code Playgroud)
但是,这失败了,因为 using 声明试图将 的所有重载foo带入范围,包括编译器正确拒绝的私有重载。
这不难解决,我也可以:
A::foo(int, bool)为 protected 或 publicA公开继承;只会foo继承的公共重载A::foo(int, bool)以便 using 声明不会尝试将其引入范围这是一个小型的私有项目,此外,该重载仅在内部调用A。所以解决这个问题在这里不是问题。(我只是要重命名私有重载。)
但感觉应该没有必要。为什么 using 声明试图将不可访问的方法带入范围?这个特殊情况是不是标准没有涵盖?除了我列出的方法之外,还有其他方法可以解决这个问题吗?
您还可以重新定义所需的重载,并将其参数转发给 中的函数A:
class B : private A
{
public:
void foo(int arg) { A::foo(arg); }
};
Run Code Online (Sandbox Code Playgroud)
在这种情况下, using 声明是一个过于生硬的工具。它将函数名称带入派生类作用域。当这个名字指的是私人的东西时,它会窒息。它无法区分重载。该标准要求 using 声明引入的名称是可访问的:
在未命名构造函数的 using 声明符中,引入声明集的所有成员都应可访问。在命名构造函数的 using 声明符中,不执行访问检查。特别是,如果派生类使用 using-declarator 访问基类的成员,则成员名称应该是可访问的。如果名称是重载成员函数的名称,则所有命名的函数都应该是可访问的。using-declarator 提到的基类成员应在指定 using-declarator 的类的至少一个直接基类的范围内可见。
转发功能也可以模板化。因此,无需重新定义他们想要单独公开的每个函数。
class B : private A
{
public:
template<typename ...Args>
void foo(Args ...args) { A::foo(args...); }
};
Run Code Online (Sandbox Code Playgroud)
它像 using 声明一样“包罗万象”,除了仅在模板实例化时检查访问说明符,即在调用函数时。因此,模板将根据其范围以及成员在A那里是否可访问而格式错误。
| 归档时间: |
|
| 查看次数: |
229 次 |
| 最近记录: |