【问题标题】:Printing from inheritance classes从继承类打印
【发布时间】:2017-09-11 04:27:47
【问题描述】:

假设我有这段代码,我想知道 main 中的代码会打印什么。输出。起初我以为当调用第一个命令时,会调用 Base 的默认构造函数,然后打印“from Base”,然后调用 A 的构造函数,然后打印“from A”。 但我不确定,因为我认为有可能是因为当我们执行此命令“Base* base = new A()”时,我怀疑可能会发生切片,所以我希望您在打印输出方面提供帮助。

最后,当我删除 base 时,那个打印应该按照我认为的顺序: 它只会调用 Base 的析构函数并从“来自 Base”。 所以因为我们主要从派生类向基类添加一个新的,我不确定。 谢谢你。

class Base {
    virtual void method() {
         std::cout << "from Base" << std::endl;
    }

public:
    virtual ~Base() {
         method();
    }
    void baseMethod() {
         method();
    }
}

class A: public Base {
    void method() {
        std::cout << "from A" << std::endl;
    }
public:
    ~A () { method();}
};


int main (void) {
    Base* base = new A();
    base -> baseMethod();
    delete base;
}

【问题讨论】:

  • 你为什么不试试呢?您的代码有一些小错误,这意味着它不会编译。所以我猜你没有?你不会得到切片,它发生在尝试对值(而不是指针或引用)使用多态性时,例如Base b = A();.
  • "Base 的默认构造函数会被调用,然后会打印 "from Base" 为什么你会再次期望呢?Base 的默认构造函数是隐式定义的,并且不会'不打印任何东西。A 的默认构造函数也不打印。
  • 我知道代码有小错误,接下来的问题是消除缺陷。但首先我需要说明它打印出的缺陷。 :)。
  • 我认为它应该打印,从 A,从 A,从 Base
  • “只会调用 Base 的析构函数” False。您已将~Base 设为虚拟 - 重点是允许通过指向基的指针正确销毁派生类的实例。

标签: c++ c++11 inheritance polymorphism abstract-class


【解决方案1】:

从您的代码稍作修改的版本开始,然后逐步进行。

它应该可以帮助您了解它的工作原理。

#include <iostream>

class Base {

// since we're going to call this from the derived class's method(), it must at least be protected    
protected:
    virtual void method() {
         std::cout << "from Base" << std::endl;
    }

public:
    virtual ~Base() {
        std::cout << "calling ~Base()\n";
        // calling a virtual method from a base class constructor or destructor may not give you the result you expect.
        // at this point, the derived class is gone. the standard says that you will actually call Base::method, not A::method
         method();
    }
    void baseMethod() {
         method();
    }
};

class A: public Base {
    void method() {
        std::cout << "from A" << std::endl;
        Base::method();
    }
public:
    ~A () {
        std::cout << "calling ~A()\n";
        method();
        }
};


int main (void) {
    Base* base = new A();
    base -> baseMethod();
    delete base;
}

预期输出:

from A
from Base
calling ~A()
from A
from Base
calling ~Base()
from Base

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-03-19
    • 1970-01-01
    • 2017-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-27
    相关资源
    最近更新 更多