Virtual function breaking private access

自闭症网瘾萝莉.ら 提交于 2020-01-04 06:01:35

问题


I recently came across this article on IBM site. Below is the sample code

#include "iostream"

class B {
public:
  virtual void f()
  {
    std::cout<<"\n In class B";
  }
};

class D : public B {
private:
    int i;

  void f()
  {
  std::cout<<"\n In class D i = "<<i;
  }
  public:
    D(int i_num):i(i_num)
    {}
};

int main() {
  D dobj(10);
  B* bptr = &dobj;
  D* dptr = &dobj;

  // valid, virtual B::f() is public,
  // D::f() is called
  bptr->f();

  // error, D::f() is private
  //dptr->f();
}

We are now able to call private function of D.I wanted to know doesn't this break C++ encapsulation ?

P.S. : Please go to Virtual function access section in Virtual function. I do not know why I am not getting exact link when I do paste.


回答1:


Access-specifiers are compile-time construct, and so, the compiler detects any violation of access-rules at compile-time (obviously) based on the static type of the object (or pointer). Such violation cannot be detected at runtime.

So bptr->f() works, because the compiler sees that the static type of bptr is B which has a public function f() defined, so the expression bptr->f() passes the compiler's test. Hence it works.

But dptr->f() doesn't work, since the static type of dptr is D which has a private function f(), hence the code wouldn't even compile!

Now whether it breaks encapsulation or not, is a very subjective question and will receive subjective answers. It entirely depends on how one defines it and the arguments directly flows from it. There is no one universal definition. My personal opinion is, if the language allows it, then (it would imply that) according to the C++ community, it doesn't break encapsulation, or if it does, then C++ allows it so as to achieve something very nobel (which otherwise isn't possible). Otherwise, I would say its just yet another misfeature of C++ just like the following:

Default argument in the middle of parameter list?




回答2:


The call bptr->f() is evaluated at run time depending on the type of objected pointed by bptr. At compile time the compile sees the bptr->f() call as call to B::f() and since B::f() is public the compiler doesn't report only error. It is only at runtime that actual function call D::f() is evaluated.

This doesn't break the Encapsulation principle this is a feature of C++ called Run-time Polymorphism or Dynamic Polymorphism

You cannot directly call dptr->f() because D::f() is declared under Private Access specifier and You cannot access privately declared members from outside the class.




回答3:


It is by design.

B::f is public. User access of f via a pointer to B is allowed. Since f is virtual, the call would be dispatched to derived classes' f.

But D::f is private, you can't access f via a pointer do D.



来源:https://stackoverflow.com/questions/5685514/virtual-function-breaking-private-access

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!