类foo充当接口,它具有纯虚函数,并且为了方便也提供了一些具有相同名称的公共重载函数,因此派生类不需要在每个实现中提供它们。
但由于派生类必须覆盖纯虚函数,因此它隐藏了foo的公共函数 我尝试使用"使用foo :: A"但它不会工作因为"使用"将带来所有功能,包括私有功能,并导致编译器错误"错误C2876:' foo' :并非所有重载都可以访问"。
class foo
{
private:
virtual void A(int a)=0;
public:
void A()
{
A(1000);
}
void A(int a, int b)
{
A(a+b);
}
};
class bar : public foo
{
private:
virtual void A(int a)
{
cout << a << "\n";
}
};
int main()
{
bar x;
x.A();
return 0;
}
我知道我可以重新定义从foo派生的每个类中的每个重载函数,但这会破坏方便的目的。
或者我可以在调用A()之前将bar转换为foo,但是这种方法会变得混乱,因为我需要记住哪个函数在哪个类中定义。例如:
class foo
{
private:
virtual void A(int a)=0;
public:
void A()
{
A(1000);
}
void A(int a, int b)
{
A(a+b);
}
};
class bar : public foo
{
private:
virtual void A(int a)
{
cout << "bar:" << a << "\n";
}
public:
void A(int a, int b, int c)
{
A(a+b+c);
}
};
class foobar : public bar
{
private:
virtual void A(int a)
{
cout << "foobar:" << a << "\n";
}
};
int main()
{
foobar x;
x.foo::A();
x.bar::A(1,2,3);
return 0;
}
我需要清楚地记得来自foo的一个没有参数,而有三个参数的A来自bar。这也不方便。
答案 0 :(得分:2)
使用非虚拟接口惯用法时,您应该以不同的方式命名这两个功能(公共非虚拟和私有虚拟)。
这很好地展示了代码的作用,并将解决您的问题:
class foo
{
private:
virtual void doA(int a)=0;
public:
void A()
{
doA(1000);
}
void A(int a, int b)
{
doA(a+b);
}
};
当然不要忘记更改层次结构。