不,你没有任何冗余。
B
类没有从其基类继承任何成员,因为它们已被声明为私有(然后只能从它们声明的类中可见和可访问)。
例如:
class A
{
private:
int _privateMember;
protected:
int _protectedMember;
public:
int _publicMember;
};
class B : public A
{
void test()
{
// This doesn't work, this field is private to the class
// where it has been declared (A)
_privateMember = 1;
// This works, a protected member is accessible inside the class
// where it's declared and derived classes.
_protectedMember = 1;
// This works, a public member is always visible and accessible.
_publicMember = 1;
}
};
void test()
{
A a;
// This doesn't work, a private field isn't accessible outside the class
// where it has been declared
a._privateMember = 1;
// This doesn't work, a protected member is accessible only inside the class
// where it has been declared and its derived classes
a._protectedMember = 1;
// This works, a public member is always visible.
a._publicMember = 1;
}
事情可能比这更复杂,你不需要总是使用公共继承,例如:
class C : protected A
{
};
void test()
{
C c;
// This doesn't work! Field is public for its class but C has inherited from A
// in a protected way (so only derived classes know that it derives from A).
c._publicMember = 1;
}
此外,您可以使用声明使一个类的所有私有成员对另一个类或函数可见friend
:
class D
{
private:
int _privateMember;
public:
int _publicMember;
friend class DFriend;
};
class DFriend
{
void test()
{
D d;
// This works, public members are accessible
d._publicMember = 1;
// This works too, this class is a friend of D
d._privateMember = 1;
}
};
也就是说,请记住,当您从基类派生时,您会说“派生类 属于基类类型”。例如,您有一个基类来描述具有某些属性的行星(为简单起见建模为公共字段):
class Planet
{
public:
int Diameter;
};
然后突然你发现你必须使它更通用,你添加了一个更通用的基类,称为 CelestialBody:
class CelestialBody
{
public:
bool canCapture(CelestialBody anotherBody)
{
// Some calculations
}
private:
vector<CelestialBody> _capturedBodies;
};
class Planet : public CelestialBody
{
public:
int Diameter;
};
现在你这样说:
- 一个天体是可以捕捉另一个天体的东西;
- 天体保留一份捕获天体的私有列表,因为它们可能会改变它的某些属性。
- 行星是天体。
- 行星有一个公共(整数)属性来描述它的直径,单位为公里。
的私有成员CelestialBody
在它之外是不可见的(一种实现细节)。世界知道 aPlanet
是 a CelestialBody
(因为公共继承),那么一切都是公开的,CelestialBody
也是公开的Planet
。
如果你不想这么说,那么你不应该简单地使用继承。看看这篇文章:
- 组合和继承:何时从另一个对象继承以及何时将另一个对象包含为字段。
- 封装:类内信息的封装。