从基类实例调用派生类'函数

时间:2015-06-04 12:11:57

标签: c++ inheritance

我是编程c ++的新用户。当我不用new创建派生实例时,它调用Base :: test()。 那么Base b = d和Base * b1 = new Derived()?

之间有什么区别?

基础课程

#include <iostream>

class Base
{
public:
    virtual void test() { std::cout << "Base::test()" << std::endl; };
};

派生类

#include "Base.h"

class Derived : public Base
{
public:
    void test() { std::cout << "Derived::test()" << std::endl; };
}

main.cc

#include "Derived.h"

int main()
{
    Derived d;
    d.test();
    Base b;
    b = d;
    b.test(); // why called Base::test() ?

    Base* b1 = new Derived();
    b1->test();
    delete b1;

    return 0;
}

3 个答案:

答案 0 :(得分:2)

  Derived d;
  d.test();
  Base b;
  b = d;
  b.test(); // why called Base::test() ?

您创建了Derived对象dBase对象b。后来分配b=d;这里发生了对象切片。作业b仅包含Base类信息的Derived部分。因此,当您致电b.test()时,它会调用Base::test()代替Derived::test()函数。

  Base* b1 = new Derived();
  b1->test();
  delete b1;

在这里,您在堆中动态创建了一个Derived类对象,并将该对象的指针返回给Base类指针。这里的指针只是保存Derived类对象的内存地址。当您调用b->test()时,系统会在内部动态识别对象的类型,并将其作为Derived返回。因此它会调用Derived::test()函数。

答案 1 :(得分:0)

因为这不是在C ++中实现多态的方式。

此:

Base b;
b = d;

第二个语句调用b的赋值运算符,即b仍然是类Base的对象b(除了数据现在可能不同,但是方法集合,即类型仍然是Base)。

您需要操作指针而不是引用,因为引用无法更改且不会更改。

答案 2 :(得分:0)

你在c ++中有两个重要概念之间的网格。

  1. 运行时多态性
  2. 对象切片
  3. 在c ++运行时,多边形是在虚函数的帮助下使用基类指针实现的。由于实际类型的对象是在运行时决定的。我们知道基类指针可以存储派生类的对象。然后调用任何函数调用派生类函数(如果base是虚函数)。

    在您的情况下,您将派生类的对象分配给基类的对象。这是Object slicing