Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/144.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 从指向派生对象的基类指针访问派生私有成员函数_C++_Inheritance_Polymorphism_Access Modifiers - Fatal编程技术网

C++ 从指向派生对象的基类指针访问派生私有成员函数

C++ 从指向派生对象的基类指针访问派生私有成员函数,c++,inheritance,polymorphism,access-modifiers,C++,Inheritance,Polymorphism,Access Modifiers,可能重复: #包括 使用名称空间std; B类{ 公众: 虚空fn1(虚空){cout访问修饰符,如public、private和protected仅在编译期间强制执行。当您通过指向基类的指针调用函数时,编译器不知道指针指向派生类的实例。根据规则,编译器可以由此推断表达式,此调用有效 降低派生类中成员的可见性通常是一种语义错误。Java和C等现代编程语言拒绝编译此类代码,因为基类中可见的成员总是可以通过基指针在派生类中访问。调用p->fn2()在运行时根据p所指向的对象类型进行计算。在编译时,

可能重复:

#包括
使用名称空间std;
B类{
公众:

虚空fn1(虚空){cout访问修饰符,如
public
private
protected
仅在编译期间强制执行。当您通过指向基类的指针调用函数时,编译器不知道指针指向派生类的实例。根据规则,编译器可以由此推断表达式,此调用有效

降低派生类中成员的可见性通常是一种语义错误。Java和C等现代编程语言拒绝编译此类代码,因为基类中可见的成员总是可以通过基指针在派生类中访问。

调用
p->fn2()
在运行时根据
p
所指向的对象类型进行计算。在编译时,编译器将
p->fn2()
调用视为对
B::fn2()
的调用,并且由于
B::fn2()
是公共的,编译器不会只报告错误。只有在运行时,实际的函数调用才是
D::fn2()
进行评估

这并没有破坏<代码>封装< /COD>原理。这是C++的一个特性,叫做“代码>运行时多态性或<代码>动态多态性

在OOP中,当派生类继承 基类,派生类的对象 类别可被称为(或铸造) 要么是基类类型,要么是 派生类类型。如果存在 基类方法被 派生类,方法调用 行为模棱两可

虚拟与虚拟的区别 非虚拟解决了这种歧义。 如果所讨论的函数是 在基类中指定为“虚拟” 然后是派生类的函数 将被调用(如果存在)。如果 不是虚拟的,基类的 函数将被调用


HTH.

当您执行
p=new D
时,
p->\uu vfptr
现在指向
D
的虚拟函数表的开始。由于这是在运行时发生的,因此访问说明符不会起作用。

这并没有回答OP关于访问修饰符的问题。我们也不会就此写签名。第11.6 i节n C++99。由于未指定,D中的fn1默认为私有。@Georg:垃圾问题标题如何帮助打破堆栈溢出的有趣示例。这个问题的标题很棒。@Tomalak Geret'kal您可以随时编辑其他问题以使用相同的标题。我正在考虑这样做。您认为如何?@Georg:Cheers:D我投t票o带着沉重的心情以dup结束这个问题。对不起,巴拉斯。@Hosam:已经完成了。虚拟函数表是一个实现细节。
vptr
&
vtbl
是编译器的实现细节,所以用它们来解释不是最好的方法。
#include <iostream>
using namespace std;

class B {
public:
  virtual void fn1(void) {cout << "class B : fn  one \n"; }
  virtual void fn2(void) {cout << "class B : fn  two \n"; }
};

class D: public B {
    void fn1(void) {cout << "class D : fn one \n"; }
private:
    void fn2(void) {cout << "class D : fn two \n"; }
};

int main(void)
{
    B *p = new D;

    p->fn1();
    p->fn2();
}