Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.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++_Oop_Inheritance - Fatal编程技术网

C++ 多态性和数据隐藏:基类是否覆盖或忽略派生类';访问限制?

C++ 多态性和数据隐藏:基类是否覆盖或忽略派生类';访问限制?,c++,oop,inheritance,C++,Oop,Inheritance,请查看以下代码列表: #include <iostream> using namespace std; class Base { public: virtual void Message() = 0; }; class Intermediate : public Base { }; class Final : public Intermediate { void Message() { cout << "Hello World!"

请查看以下代码列表:

#include <iostream>

using namespace std;

class Base {
public:
    virtual void Message() = 0;
};

class Intermediate : public Base {

};

class Final : public Intermediate {
    void Message() {
        cout << "Hello World!" << endl;
    }
};

int main() {
    Final final;
    /* Wont work (obviously):
    Final* finalPtr = &final;
    finalPtr->Message();
    */
    // Works:
    Intermediate* finalPtr = &final; // or Base* finalPtr = &final;
    finalPtr->Message();

    return 0;
}
#包括
使用名称空间std;
阶级基础{
公众:
虚空消息()=0;
};
中级班:公共基地{
};
期末班:公共中级{
无效消息(){
cout消息();
返回0;
}
注意到以下几点:

  • 在抽象的Base类中,纯虚拟函数message()是公共的
  • Intermediate类(也是抽象类)继承自Base类(在Intermediatemessage()函数是否仍然是公共的纯虚拟函数?)
  • Final类继承自中间类,并且message()函数是私有的(默认情况下)
  • 在main中,创建类型为Final的对象
  • 创建指向最终对象的中间指针
  • 问题: 如果运行该程序,行finalPtr->Message();通过其private成功调用FinalMessage()函数的实现。这是如何发生的?基类是否覆盖或忽略派生类的访问限制

    相关问题: 关于上面的(2.),定义中间类的正确方法是什么?是否需要从基类中重新声明纯虚拟函数message(),记住中间类不打算提供实现

    注意:代码已使用Digital Mars编译器(dmc)和Microsoft的Visual Studio编译器(cl)进行了测试,在这两种编译器中都运行良好

    这是如何发生的?基类是否覆盖或忽略派生类的访问限制

    通过公共继承,基类的所有公共成员都将成为派生类的公共成员。因此,Yes
    Message()
    中间类中的公共函数

    该函数是在基类(
    中间
    )指针上调用的。该函数在基类中是公共的。动态分派(即对派生类函数的实际调用)仅在运行时发生,因此这是有效的

    以上原因是,在运行时,访问说明符没有任何意义,访问说明符规则只在编译时解析并生效

    如果在派生类指针上调用函数,则编译器在编译时检测到
    Message()
    Final
    中声明为
    private
    ,因此给出错误


    当从抽象类派生时,派生类必须基类的所有纯虚函数提供定义,否则将导致派生类也成为抽象类


    <> >代码>中间< /COD>类是一个抽象类,只要不需要创建这个类的对象,它就可以工作。注意,可以创建一个抽象类的指针。C++中的

    < P>,虚拟和访问说明符是互斥的。这就是为什么在C++中,可以缩小访问虚拟方法WH的权限。在C#或Java中使用EREA是不可能的

    当您试图通过基类指针访问虚拟函数时,编译器编译代码,因为基类的虚拟函数是公共的


    在您的注释代码中,具有受限访问权限的虚拟函数是通过最后一个类指针调用的。因此出现编译错误。

    谢谢@Als。我只是有一条评论:“使用公共继承,基类的所有公共成员都将成为派生类的公共成员。”如果您查看注释代码,Final类型的指针不会调用message()函数。这意味着Final类认为该方法是私有的,但其基类不会。这是谜团的一部分。@JohnGathogo:更新以回答您的查询。“动态分派(即对派生类函数的实际调用)只有在运行时才会发生,因此这是有效的”-这将解释为什么它有效“您可以创建一个指向抽象类的指针。”我希望如此,否则
    virtual
    函数的用处会小得多。:P这是“接口”模式的基础。我现在做了很多关于抽象/纯虚拟基的工作,这些抽象/纯虚拟基由异构模板类型继承,等等。