【发布时间】:2010-04-19 22:54:57
【问题描述】:
假设您有一个类,该类使用访问说明符 public 定义虚拟方法。 您可以更改覆盖方法上的访问说明符吗? 我假设没有。 寻求解释。
【问题讨论】:
标签: c++ overriding
假设您有一个类,该类使用访问说明符 public 定义虚拟方法。 您可以更改覆盖方法上的访问说明符吗? 我假设没有。 寻求解释。
【问题讨论】:
标签: c++ overriding
答案是:有点。您只能更改派生类有权访问的成员的访问权限。继承的类型没有影响 - 这仅控制继承成员的默认访问(在某种程度上,遵循其他规则)。
因此,您可以将基类的受保护成员设为公开或私有;或基地的公共成员受保护或私有。但是,您不能将基地的私人成员设为公开或受保护。
例子:
class Foo
{
protected:
void protected_member();
private:
void private_member();
public:
void public_member();
};
class Bar : private Foo
{
public:
using Foo::protected_member;
using Foo::private_member;
using Foo::public_member;
};
int main(int, const char**)
{
Bar bar;
return 0;
}
上述代码在 g++ 4.1.2 上引发以下错误:
main.C:7: 错误:'void Foo::private_member()' 是私有的
main.C:14: 错误:在此上下文中
此外,覆盖与更改方法的访问权限无关。您可以覆盖虚拟私有方法,但不能从派生类中调用它。
【讨论】:
是的,你可以,但它“不能理解”。
看看Overriding public virtual functions with private functions in C++
【讨论】:
你绝对可以。但这没有任何意义。如果它是公共继承,那么您始终可以将对象强制转换为其基类。如果是私有继承,默认情况下所有基方法都已经是私有的。在受保护继承的情况下,您可以将基方法设为私有,这样您就可以防止可能的派生类调用它,但我真的不明白为什么需要它。
【讨论】:
是的,你可以,事实上你甚至不需要覆盖或使用虚拟的任何东西。
class ABC {
public: // or this may be protected, no difference
void woof();
void moo();
};
class D : private ABC { // now woof and moo are private
public:
using ABC::woof; // using declaration to make woof public again
ABC::moo; // access declaration (deprecated) does the same
};
如果它们是虚拟的,也同样有效。或者,正如其他人所指出的,虚函数查找忽略了实现类指定的访问;您可以转换为的任何类都可以在编译时提供访问权限。
另一方面,如果没有D 中的特殊声明,ABC 的public 接口确实无法通过D 访问,因为您将无法向上转换为ABC。如果woof 和moo 是virtual,你会想要覆盖private 来隐藏它们。也许这样更好地回答了这个问题。
【讨论】:
private 和 class ABC,那会有很大的不同。 class D 必须有权访问基本成员,然后才能在 using 声明中成功命名它们。 OTOH,他们本来可以在ABC 中使用protected,并且仍然可以使用。