虚函数破坏私有访问

发布于 2024-11-01 21:40:43 字数 778 浏览 3 评论 0原文

我最近在 IBM 站点。下面是示例代码

#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();
}

我们现在可以调用 DI 的私有函数,想知道这是否会破坏 C++ 封装?

PS:请参阅虚拟功能中的虚拟功能访问部分。我不知道为什么粘贴时没有得到确切的链接。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

爱要勇敢去追 2024-11-08 21:40:43

调用 bptr->f() 在运行时根据 bptr 指向的对象类型进行评估。在编译时,编译将 bptr->f() 调用视为对 B::f() 的调用,并且自 B::f()< /code> 是 public 编译器不仅仅报告错误。仅在运行时才会评估实际的函数调用 D::f()

这并没有违反封装原则,这是C++的一个特性,称为运行时多态性动态多态性

你不能直接调用dptr->f() 因为 D::f() 是在 Private 访问说明符下声明的,并且您无法从类外部访问私有声明的成员。

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.

冷︶言冷语的世界 2024-11-08 21:40:43

访问说明符是编译时构造,因此,编译器(显然)根据对象(或指针)的静态类型在编译时检测到任何违反访问规则的行为。这种违规行为无法在运行时检测到。

所以 bptr->f() 可以工作,因为编译器认为 bptrstatic 类型是 B其中定义了 public 函数 f(),因此表达式 bptr->f() 通过了编译器的测试。因此它有效。

但是 dptr->f() 不起作用,因为 dptr 的静态类型是 D,有一个私有函数f(),因此代码甚至无法编译!

现在是否破坏封装,是一个非常主观的问题,并且会得到主观的答案。这完全取决于人们如何定义它以及直接从中得出的论点。没有一个通用的定义。我个人的观点是,如果语言允许,那么(这意味着)根据 C++ 社区,它不会破坏封装,或者如果它破坏了封装,那么 C++ 允许它实现一些非常诺贝尔的东西(否则是不可能的)。否则,我会说它只是 C++ 的另一个错误功能,如下所示:

默认参数在参数列表中间?

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?

寒冷纷飞旳雪 2024-11-08 21:40:43

这是设计使然。

B::f 是公开的。允许用户通过指向B的指针访问f。由于 f 是虚拟的,因此调用将被分派给派生类的 f

但是D::f是私有的,你不能通过指针doD访问f

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文