首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >关于虚函数

关于虚函数
EN

Stack Overflow用户
提问于 2021-06-11 22:57:56
回答 1查看 73关注 0票数 0

我有以下代码片段:

代码语言:javascript
复制
#include <iostream>
#include <typeinfo>
using namespace std;

class A{
public:
    int x;
    A(int i = 0): x(i) {}
    A minus(){
        return 1 - x;
    }
    virtual void print(){
        cout << x << "\n";
        cout << "Base print\n";
    }
};

class B: public A{
    int y;
public:
    B(int i = 0) {x = i;}
    void print(){
    cout << x << "\n";
    cout << "Derived print!\n";
    }
   };

int main(){
    A* p1 = new B(18);
    *p1 = p1->minus();
    p1->print();

    return 0;
}

输出为:

代码语言:javascript
复制
-17
Derived print!

我知道-17从哪里来。它执行向上转换和A* p1 = new B(18),并使p1指向x值为18的派生对象。*p1 = p1->minus使p1指向的对象是A(-17) /// cause 1 -18 = -17。我的问题是,第二行是从哪里来的?如果p1指向*p1 = p1->minus()之后的A对象,为什么p1->print()不打印"Base print"

EN

回答 1

Stack Overflow用户

发布于 2021-06-11 23:07:28

您创建了一个class B类型的对象

代码语言:javascript
复制
A* p1 = new B(18);

所以指针p1将指向这个对象,直到它(指针)被重新赋值。

在此语句中

代码语言:javascript
复制
*p1 = p1->minus();

未删除class B类型的动态创建的对象。使用由class A的编译器复制赋值运算符隐式定义的,只更改了class A类型的子对象,并且指针p1仍然指向class B类型的同一对象。

因此,在下面的语句中

代码语言:javascript
复制
p1->print();

有一个叫做class B类型对象的虚函数,顺便说一下,它至少应该像这样在class B中声明

代码语言:javascript
复制
void print() override
{
    //..
}

注意,您应该在类A中声明一个虚拟析构函数。例如

代码语言:javascript
复制
virtual ~A() = default;

在退出main之前,您应该删除动态分配的对象。

代码语言:javascript
复制
delete p1;
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67939271

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档