说我有这个例子:
class A1
{
private:
string name;
}
class A
{
private:
A1* field;
}
class B1 : public A1
{
private:
int id;
}
class B : public A
{
private:
B1* field;
}
所以在这种情况下,我会在我的B班:
那么我该怎么做才能避免这种冗余?
答案 0 :(得分:2)
我在这里看不到任何冗余。让我们将类重命名为更有用的东西:
class Animal // A1
{
private:
string name;
}
class Person // A
{
private:
Animal* housePet;
}
class Dog : public Animal // B1
{
private:
int breedId;
}
class DogTrainer : public Person // B
{
private:
Dog* trainee;
}
你知道,没有一个领域可以安全地消除。 trainee
与housePet
不同,每个name
都需要单独的{{1}}。
答案 1 :(得分:1)
不,你没有任何裁员。
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
的私有成员在其外部不可见(实现细节类型)。世界知道Planet
是CelestialBody
(由于公共继承),CelestialBody
中的所有内容都是公开的Planet
。
如果您不想说,那么您不应该只使用继承。看看这篇文章: