1

说我有这个例子:

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 课上:

  1. B1 类的 id 属性
  2. name 属性来自类 A 的继承。
  3. 另一个名称属性来自于从类 A1 继承的 B1 类。

那么我应该怎么做才能避免这种冗余呢?

4

2 回答 2

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;
}

你看,没有一个领域可以安全地消除。thetrainee和 the 不一样housePet,它们每个都需要一个单独的name.

于 2012-04-19T09:24:52.963 回答
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在它之外是不可见的(一种实现细节)。世界知道 aPlanet是 a CelestialBody(因为公共继承),那么一切都是公开的,CelestialBody也是公开的Planet

如果你不想这么说,那么你不应该简单地使用继承。看看这篇文章:

  • 组合和继承:何时从另一个对象继承以及何时将另一个对象包含为字段。
  • 封装:类内信息的封装。
于 2012-04-19T09:12:43.403 回答