Do these two classes violate encapsulation?

2020-06-16 01:25发布

class X
{
protected:
    void protectedFunction() { cout << "I am protected" ; }
};

class Y : public X
{
public:
    using X::protectedFunction;
};

int main()
{
    Y y1;
    y1.protectedFunction();
}

This way I am able to expose one of the functions of the base class.

  1. Doesn't this violate the encapsulation principle?
  2. Is there a specific reason as to why this is in standard?
  3. Is there any uses of this, or is it going to be changed in the new standard?
  4. Are there any open issues related to this in the standard?

10条回答
闹够了就滚
2楼-- · 2020-06-16 02:16

Class designer should know that declaring a member function or variable (though all variables should be private, really) as protected is mostly the same as declaring it public (as you showed it's easy to get access to protected stuff). With that in mind, care as to be taken when implementing those functions in the base class to account for "unexpected" use. It's not a violation of encapsulation because you can access it and expose it.

protected is just a more complicated way of declaring something public!

查看更多
祖国的老花朵
3楼-- · 2020-06-16 02:17

Personally I think this question should be answered as more of a design question rather than a technology question.

I would ask, "What was the point of the protected method in the first place?" Was it a method that only subclasses should call, or is it a method that subclasses should override? However, it may be a method that is not expect in a generic base class, but maybe expected in a subclass. To the client of the base class they never knew about that protected method. The creator of the subclass chose to expand the contract and now that protected method is public. The question really should be not does C++ allow it, but is it right for you class, contract and future maintainers. Sure it might be a bad smell, but really you need to make it right for the use case involved.

If you do make the protected method public then make sure you properly provide internal documentation for the maintainer explaining the rationale of why this particular decision is made.

In general though, for safety sake as a previous contributor mentioned, you probably want to use a delegate function (with a different name) in the subclass. So instead of "get(int)" you might have "getAtIndex(int)" or something. This allows you to more easily refactor/protect/abstract/document that in the future.

查看更多
时光不老,我们不散
4楼-- · 2020-06-16 02:19

No. protectedFunction() is protected. You are free to call it from derived classes, so you could have called it directly from a public member of Y, and call this public member from main().

If you could have done that with a private method, there would have been a problem... (EDITED to be a bit clearer).

查看更多
再贱就再见
5楼-- · 2020-06-16 02:20

In C++ even private modifier doesn't guarantees encapsulation. No one can stop you from shooting yourself in your foot.

Herb Sutter in his article "Uses and Abuses of Access Rights" demostrates different ways how you can "break encapsulation".

Here funny example from Herb's article.

Evil macro magic

#define protected public // illegal
#include "X.h"
//...
X y1;
y1.protectedFunction();
查看更多
登录 后发表回答