这里是否违反了封装的概念

Is Concept of Encapsulation Violated here?

本文关键字:封装 是否 这里      更新时间:2023-10-16
#include<iostream>
class A {
public:
  int a;
protected:
  void func() {
  std::cout<<"protected member"<<endl;
  }
};
class B:public A
{
public:
  using A::func;  //Isn't this violation of encapsulation?
};
int main(){
B b;
b.func();
return 0;
}

为什么上面的代码运行成功?

它不违反封装的概念吗?

如果我错了,请纠正我。

这是一个有趣的问题,我认为它突出了 c++ 封装的一个重要且经常被忽视的方面。

我的回答是"是的,封装被违反了,但不是你想的那样"。实际违规行为是首先宣布该方法protected

您的代码很好地演示了与子类的受保护关系的问题......他们可以轻松地解除对你的保护。另一种说法是,如果你要使一个成员protected,你也可以让它public,因为实际上protectedpublic,如果你的子类想要它。

这在实践中意味着什么?

这意味着如果你使一个成员函数protected,它永远是类接口的一部分。因此,您必须像对待任何其他公共成员功能一样认真对待它,实际上就像对待它是公共成员功能一样

也就是说,它应该是尽可能无状态的,具有尽可能少的前提条件,并且如果您更改实现,则对整个对象的逻辑效果必须保持不变。

您展示的示例并不违反封装,因为允许子类在它们继承的内容之上添加公共成员,并且还允许它们访问它们继承的受保护成员。

在你的例子中,A的一个子类B决定添加一个名为func的新成员函数,其实现恰好由A::func的单个调用组成。

通常,protected成员应被视为类接口的一部分,以及public成员。尽管它们的可见性仅限于子类,但受保护成员不是类实现的一部分,因为对受保护成员命名或语义的任何更改都需要与对类的所有子类的更改进行协调。