当在声明它的父类的实例上调用纯虚函数时会发生啥?

Posted

技术标签:

【中文标题】当在声明它的父类的实例上调用纯虚函数时会发生啥?【英文标题】:What happens when a pure virtual function is called on an instance of the parent class in which it is declared?当在声明它的父类的实例上调用纯虚函数时会发生什么? 【发布时间】:2019-03-29 01:16:53 【问题描述】:

我是 C++ 新手,在我最近使用的一些代码中遇到了一个有趣的问题。假设我们有以下类:ParentChild_AChild_BChild_C

class Parent 
    ...
    virtual int Foo() = 0;
    ...



class Child_A : Parent 
    ...
    int Foo()  return 1; 
    ...


class Child_B : Parent 
    ...
    int Foo()  return 2; 
    ...


class Child_C : Parent 
    ...
    int Foo()  return 3; 
    ...

现在我知道如果我这样做会发生什么:

std::unique_ptr<Child_A> a = std::make_unique<Child_A>();
Parent *p = &a;
p->Foo();

这将返回 1。但我的问题是,如果我这样做会发生什么:

std::unique_ptr<Parent> p = std::make_unique<Parent>();
p->Foo();

感谢任何可以提供帮助的人!

编辑:事实证明,无论我尝试修复语法多少次,我的问题都没有任何意义。不能像那样在父级上调用纯虚函数。后来我发现我正在寻找的代码在调用该函数之前确实将父类设置为它的一个子类(定义了虚函数)的成员......我之前只是错过了它。

【问题讨论】:

你不能实例化Parent,因为它是抽象的。如果您尝试,编译器会抱怨。而Parent p = a 将导致 object slicing (可能还有编译器错误)。我想你的意思是 Parent *p = &amp;a 或类似的。 你完全正确。编辑以解决该问题和其他问题。好久没用过C了,现在才学C++,很多这些看似很小的细节都让我头疼。 Child_A a = new Child_A(); 应该是Child_A * a = new Child_A();(因为new 返回一个指针,你不能将指针分配给非指针)然后Parent *p = &amp;a; 变成Parent *p = a; 或者你可以直接切换到Parent *p = new Child_A(); 另外,C++ 不是 Java。使用std::make_unique&lt;Type&gt; 而不是new Type();。后者必然会在未来引起重大问题,因为 new 表明您个人负责管理与对象关联的内存。 就在@Isaiah 的页面上,并且会更进一步。您会发现几乎完全使用自动变量而不使用动态分配有很大的优势。一般来说,偏好应该按顺序排列:Automatic Variable、Library container 或 Smart pointer、newmalloc 和家人。 【参考方案1】:

您对 C++ 语法有一点误解,尽管事实上您的类不是从父类继承的。

当你声明一个像 void foo() = 0 这样的成员函数时,你是在说你的函数没有实现并且你正在使你的类抽象,你不能实例化一个抽象类。纯虚函数并不意味着“返回 0”。

【讨论】:

我编辑了我的帖子以获得正确的语法。感谢您的回答。【参考方案2】:

如果您希望能够实例化父函数,可以将函数设为虚拟(不是纯虚拟),然后让子函数覆盖该函数。

【讨论】:

以上是关于当在声明它的父类的实例上调用纯虚函数时会发生啥?的主要内容,如果未能解决你的问题,请参考以下文章

具有纯虚函数的父类的指针数组和指针数组的对象类型

虚函数本质

delphi中覆盖override父类的静态方法和虚函数有啥不同?

C++之多态性

C++ 纯虚函数

5_面向对象-中之子类对象实例化全过程