例如,class Base有两个公共方法:foo()和bar().类Derived继承自类Base.在课堂上Derived,我想foo()公开但bar()私下.以下代码是正确和自然的方式吗?
class Base {
public:
void foo();
void bar();
};
class Derived : public Base {
private:
void bar();
};
Run Code Online (Sandbox Code Playgroud)
Bri*_*ndy 91
C++ '03标准的第11.3节描述了这种能力:
11.3访问声明
通过在派生类声明中提及其qualified-id,可以在派生类中更改基类成员的访问权限.这种提及称为访问声明.访问声明qual-id的效果; 被定义为等同于使用qualified-id的声明
所以有两种方法可以做到.
注意:从ISO C++ '11开始,
Base::bar;如注释中所述,禁止访问声明().using Base::bar;应该使用using-declaration()代替.
1)您可以使用公共继承,然后使栏私有:
class Base {
public:
void foo(){}
void bar(){}
};
class Derived : public Base {
private:
using Base::bar;
};
Run Code Online (Sandbox Code Playgroud)
2)你可以使用私有继承,然后使foo公开:
class Base {
public:
void foo(){}
void bar(){}
};
class Derived : private Base {
public:
using Base::foo;
};
Run Code Online (Sandbox Code Playgroud)
注意:如果你有一个Base类型的指针或引用,它包含Derived类型的对象,那么用户仍然可以调用该成员.
Jam*_*lis 13
实际上没有办法做你想做的事情,因为如果你公开派生Base,那么班级的用户将始终能够:
Derived d;
Base& b = d;
b.bar();
Run Code Online (Sandbox Code Playgroud)
在基类的类派生publicy中使公共基类函数不可访问是"正确或自然的"; 相反,应该重构基类接口,使这些函数不公开或分成单独的类.
首先,您必须从OOP角度了解您想要做什么.有两种完全不同的继承类型:
接口的继承.当您implement使用Java或其他语言将接口作为独立实体时,当您从C++中公开继承空抽象类时,也会发生这种情况.在这里,你不关心代码在所有,但想用你的基础要告诉你的编译器和人人/派生类,这个派生类是一种特殊的,你的基类,它拥有所有的基类的属性,它的行为正是为基类在其用户可见的范围内执行,并且可以在任何算法中使用而不是基类.
代码的继承.您在基类中有一段代码要在派生类中重用.基类和派生类不必以任何方式相关,您只想重用代码,就是这样.
C++中的公共继承是两种类型的混合,您获得了接口继承,并且您也获得了代码继承.私有继承是一种不同类型的野兽,你只获得代码继承,派生类的用户不能使用它而不是基类,而且从用户的角度来看,基类和派生类没有任何关系.
struct Base {};
struct PublicDerived : public Base {};
struct PrivateDerived: private Base {};
Base * base; PublicDerived * public_derived; PrivateDerived * private_derived;
base = public_derived; //good
base = private_derived; //compilation error.
Run Code Online (Sandbox Code Playgroud)
由于您想要更改接口,因此您不应该使用公共继承,通过更改接口,您可以有效地说这两个类具有不同的行为,并且不能互换使用.所以你真正想要的是私下继承,然后制作你想要公开的所有方法,而不是相反.