C++中的公有继承,保护继承和私有继承说明
1. C++ 中的三种继承类型
在 C++ 里,继承可以指定访问权限修饰符:
class Derived : public Base { ... } // 公有继承
class Derived : protected Base { ... } // 保护继承
class Derived : private Base { ... } // 私有继承
它们的主要区别是 基类的成员在派生类中的可见性,以及派生类通过对象使用时的访问权限。
2. 基类到派生类的成员可见性变化
假设基类 Base 有三种成员:
public公有成员protected受保护成员private私有成员
| 继承方式 | 基类 public 在派生类中 | 基类 protected 在派生类中 | 基类 private 在派生类中 |
|---|---|---|---|
| public | public → public | protected → protected | ‑(不可访问) |
| protected | public → protected | protected → protected | ‑(不可访问) |
| private | public → private | protected → private | ‑(不可访问) |
总结:
- 公有继承:基类的接口保持原来的可见性(对外接口不会被屏蔽)。
- 保护继承:基类的 public 接口变成 protected,对外不可直接用,只能在子类中用。
- 私有继承:基类的所有访问权限全部变成 private,对外完全隐藏。
3. 对外表现的差异
公有继承
- 语义上属于 “is-a” 关系:
Derived是一个Base。 - 外部代码可以通过
Derived对象直接使用基类的 public 方法。 - 在 ROS 2 中,像
Node2Go : public rclcpp::Node就意味着 Node2Go 是一个 ROS 节点,外部可以直接把它传给需要rclcpp::Node的地方。
保护继承
- 表现出 “be-an-implementation-of” 的关系,更多是内部实现。
- 外部无法通过派生类对象调用基类 public 方法(因为已变成 protected)。
- 常用于封装,但保留派生类对基类方法的访问。
私有继承
- 表现出 “is-implemented-in-terms-of” 的关系:派生类内部用基类功能实现,但对外隐藏。
- 派生类对象不能在需要基类对象的地方直接用。
- 类似于组合(“has-a”),只是用继承实现。
4. 为什么 ROS 2 节点类用 公有继承
- ROS 2 的许多 API 需要接受
std::shared_ptr<rclcpp::Node>或直接rclcpp::Node类型参数。 - 如果是 public继承,
Node2Go对象可以直接替代rclcpp::Node。 - 保留
rclcpp::Node提供的所有 public 方法,让你可以直接调用create_publisher()、create_subscription()等。
✅ 一句话总结:
- public 继承:派生类“是”基类,对外公开基类接口。
- protected 继承:派生类内部“是”基类,对外隐藏基类接口。
- private 继承:派生类内部用基类实现功能,对外看起来“不是”基类,接口也全被隐藏。
