有关此主题的足够信息。例如,这个帖子对我来说非常清楚:Difference between private, public, and protected inheritance
除了一点;为什么有用?
答案 0 :(得分:10)
使用公共继承来反映 is-a relationship 。这是继承的主要用途,尤其是与虚函数结合使用时。它允许重用接口,不仅可以通过新代码重用旧代码,还可以通过旧代码重用新代码! (因为在运行时调度虚函数)。
在特殊情况下,请使用私有继承来反映已实现的关系。这是一种常用的模式,通常可以通过组合达到相同的目标(将可能的基类作为数据成员)。另一个缺点是,您可以轻松地对同一基类进行多次继承(删除两次或更多次),从而导致所谓的Diamond Problem。
避免使用受保护的继承,它表明您的类接口是依赖于客户端的(派生类与世界相对)。通常这是由于具有多个责任的类,这表明重构成单独的类是合适的。
答案 1 :(得分:2)
这个问题的答案涉及类接口和数据封装,而不是语言功能。
受保护和私有继承的用例相当有限,因为通常有其他选项可以更好地解决问题(例如使用组合,而不是继承)。但是,有时候你必须必须从某种类型继承(例如与第三方库接口),但你强烈更喜欢(由于与您的类的用户界面)隐藏从新类型的用户继承的基类的大多数成员。一个典型的场景是当你需要你的类型让某个类的成员函数供内部使用时,如果从类本身外部调用它,它将破坏你的新类型的逻辑。
在这些情况下,您需要使用private
或protected
继承(取决于接口是否应该类似地限制为其他派生类。
但请记住,这只是(强烈)暗示你的班级用户如何使用它。您正在调整其公共接口以隐藏其基类中公开的某些功能。这并不严格地说阻止人们访问这些成员,因为任何人仍然可以将指向派生类的指针强制转换为指向基础的指针,并以这种方式到达“隐藏”资源。
答案 2 :(得分:1)
所有关于数据封装。
http://en.wikipedia.org/wiki/Encapsulation_(object-oriented_programming)
最好保护班级的“内部”数据与其他班级保持一致。好处包括:
选择使用protected
代替private
也可以让您的代码更容易通过子类扩展。
答案 3 :(得分:1)
私有:只能从类函数,构造函数和析构函数访问类的私有成员。将使用您的课程的客户将无法访问它们。因此,如果您正在实现列表类并且想要跟踪列表的大小,那么您应该有一个私有变量(例如listSizeP
)。这样做是因为您不希望客户端能够在不插入元素的情况下修改列表的大小。
Public:公共成员。在上面提到的列表示例中,insert
和erase
等函数应该是公开的。
受保护:类的受保护成员(如私有成员)只能从类函数访问,但它们也可以由此类继承的类访问(实际上它取决于派生类继承基类。如果它不是公共继承,则派生类不能访问基类的私有成员。这就是最常见的继承方式是公共继承)。例如:
#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;
}