13

好吧,关于这个主题有足够的信息。例如,这个线程对我来说很清楚:私有、公共和受保护继承之间的区别

除了一点;为什么有用?

4

4 回答 4

11

使用公共继承来反映is-a 关系。这是继承的主要用途,尤其是与虚函数结合使用。它允许重用接口,不仅是新代码重用旧代码,还允许旧代码重用新代码!(因为在运行时分派虚函数)。

在特殊情况下,使用私有继承来反映is-implemented-in-terms-of 关系。这是一个经常被过度使用的模式,通常可以通过组合(将可能的基类作为数据成员)来达到等效的目标。另一个缺点是您可以轻松地对同一基类进行多重继承(删除两次或多次),从而导致所谓的钻石问题

避免使用受保护的继承,它表明您的类接口是客户端相关的(派生类与世界)。这通常是由于类具有多种职责,建议将其重构为单独的类是合适的。

于 2013-01-19T12:28:01.277 回答
3

这个问题的答案涉及类接口和数据封装,而不是语言能力。

受保护和私有继承的用例相当有限,因为通常有其他选项可以更好地解决问题(例如使用组合,而不是继承)。但是,有时您必须从某种类型继承(例如与第三方库接口),但您强烈希望(出于与类的用户界面相关的原因)隐藏从基类继承的大多数成员来自您的新类型用户的课程。一个典型的场景是当您需要您的类型具有某个类的成员函数以供内部使用时,但是如果从类本身外部调用它会破坏您的新类型的逻辑。

在这些情况下,您需要使用privateprotected继承(取决于接口是否应该类似地限制为进一步的派生类。

但是请记住,这只是(强烈)向您班级的用户暗示他们应该如何使用它。您正在调整其公共接口以隐藏其基类中公开的某些功能。严格来说,这并不能阻止人们访问这些成员,因为任何人仍然可以将指向派生类的指针转换为指向基类的指针,并以这种方式访问​​“隐藏”资源。

于 2013-01-19T12:35:12.130 回答
1

这都是关于数据封装的。

http://en.wikipedia.org/wiki/Encapsulation_(面向对象编程)

封装概念

保护您的类的“内部”数据免受其他类的影响是很好的。好处包括:

  • 其他类必须通过已知的正确访问机制(例如方法)来访问您的类,并且不能直接使用您的类的内部(因此可能会使您的类进入一些未知和损坏的状态)
  • 您可以更改班级的内部运作,并知道其他班级不会因此而中断
  • 减少与课程的可见外部接触点,使您的课程更易于使用和理解

选择使用protected而不是private也使您的代码更容易通过子类化进行扩展。

于 2013-01-19T12:22:11.410 回答
1

Private:类的私有成员只能从类函数、构造函数和析构函数中访问。将使用您的课程的客户将无法访问它们。因此,例如,如果您正在实现一个列表类并且想要跟踪列表的大小,那么您应该有一个私有变量(listSizeP例如)。您这样做是因为您不希望客户端能够在不插入元素的情况下修改列表的大小。

公共:公共成员也可以被客户端访问。在上面提到的列表示例中,函数inserterase应该是公共的。

protected:类的protected成员,和private成员一样,只能从类函数中访问,但也可以被该类继承的类访问(实际上取决于派生类继承基类的方式。如果不是公有继承,那么派生类就不能访问基类的私有成员。这就是为什么最常见的继承方式是公有继承)。例子:

#include <iostream>

using namespace std;

class Base {
public:
    int num;
public:
    Base(int x=0) : num(x) {}
};

class Derived : public Base {
public:
    Derived(int x=0) : Base(x) {}
    void tell() { cout << "num: " << num << endl; }
};

int main() {
    Derived D(4);
    D.tell(); // would cause error if num was private
    return 0;
}
于 2013-01-19T12:37:02.180 回答