这里是否违反了封装的概念
Is Concept of Encapsulation Violated here?
#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
,因为实际上protected
是public
,如果你的子类想要它。
这在实践中意味着什么?
这意味着如果你使一个成员函数protected
,它永远是类接口的一部分。因此,您必须像对待任何其他公共成员功能一样认真对待它,实际上就像对待它是公共成员功能一样。
也就是说,它应该是尽可能无状态的,具有尽可能少的前提条件,并且如果您更改实现,则对整个对象的逻辑效果必须保持不变。
您展示的示例并不违反封装,因为允许子类在它们继承的内容之上添加公共成员,并且还允许它们访问它们继承的受保护成员。
在你的例子中,A
的一个子类B
决定添加一个名为func
的新成员函数,其实现恰好由A::func
的单个调用组成。
通常,protected
成员应被视为类接口的一部分,以及其public
成员。尽管它们的可见性仅限于子类,但受保护成员不是类实现的一部分,因为对受保护成员命名或语义的任何更改都需要与对类的所有子类的更改进行协调。
相关文章:
- 在提升multi_index容器中,是否定义了"default index"?
- 在C++STL中是否有Polyval(Matlab函数)等价物?
- 检查输入是否不是整数或数字
- 是否可以初始化不可复制类型的成员变量(或基类)
- 在C++中,是否可以基于给定的标识符创建基类的新实例,反之亦然
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 是否可以通过C++扩展强制多个python进程共享同一内存
- 此代码是否违反一个定义规则
- 是否需要删除包含对象的"pair"?
- 是否可以从int转换为enum类类型
- 是否有更好的方法来封装成员对象可以访问的共享存储池?
- 使用 stl 迭代器封装向量是否很好?如果是?怎么可能呢?
- 假设钻石继承打破了C++的封装是否正确?
- 我是否应该将最后一个“返回”语句封装为“else { return .. }',如果它在逻辑上是可选的
- 外部是否破坏封装
- 传递 lambda 在使用私有成员变量时是否违反封装
- 这里是否违反了封装的概念
- 对象切片是否会破坏封装
- 我的GLSL着色器对象/包装器是否应该封装加载/设置VertexArrayObject
- 公共静态常量变量是否破坏了封装意识形态