【问题标题】:Is Concept of Encapsulation Violated here?这里违反了封装的概念吗?
【发布时间】:2015-12-27 07:26:53
【问题描述】:
#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;
}

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

不违反封装的概念吗?

如果我错了,请纠正我。

【问题讨论】:

  • “封装”是什么意思?
  • 由 B 的设计者决定使用什么接口,包括提供对 A 的受保护成员的访问权限。
  • 为什么上面的代码运行不成功?为什么会违反封装的概念?既然它没有,你需要先向我们解释你的错误信念,然后我们才能纠正它。
  • 我看到您还发布了有关 Java 的问题。当涉及到编程的“概念”时,C++ 和 Java 有很多不同之处。它们在很多方面都是非常不同的语言。这是其中之一。
  • 所以事实证明,我不需要像这样显式继承受保护的成员 `class B: protected A`。如果我仍然错了,请纠正我。

标签: c++ oop encapsulation


【解决方案1】:

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

我的回答是“是的,封装被违反了,但不是你想的那样”。实际违规之处在于首先将方法声明为protected

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

这在实践中意味着什么?

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

也就是说它应该尽可能无状态,前提条件尽可能少,如果你改变实现,对整个对象的逻辑影响必须保持不变。

【讨论】:

  • 谢谢,这就是我想要的解释。
  • 确实如此。将实现细节声明为protected 似乎是初学者的常见错误。我记得当我刚接触 C++ 时自己做的。多年的经验表明,protected 几乎没有用处。几乎所有成员都应该是publicprivate
【解决方案2】:

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

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

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

【讨论】:

  • func() 受到保护怎么办?
  • @ShubhamBatra:怎么样? protected 字面意思是派生类可以访问该符号,所以没有问题。你把protectedprivate 混淆了吗?
  • @ShubhamBatra 只有A::func() 受到保护; B::func() 不受 B 类设计者的明确选择保护。
  • @ShubhamBatra - B 也可以添加 void another_func() { func(); }。有什么区别?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-09-20
  • 2013-10-17
  • 2017-06-03
  • 1970-01-01
  • 2017-03-28
  • 2016-05-08
  • 2011-04-23
相关资源
最近更新 更多