提问者:小点点

实例是为哪个类创建的,派生类在这段代码中做什么?


派生类在此代码中的作用如下:

class Base
{
public:
       virtual std::string Name(){ return "Base Class"}

};
class Derived : public Base
{
 public:
        std::string Name() {return "Derived Class"}
}

int main()
{
   Base* object = new Derived();
   return 0;
}

我在学习教程,但不明白基类实例化中的派生类在上面的代码中做了什么。


共2个答案

匿名用户

我们的目标是实现多态性,这是一个OOP概念,它允许您使用派生类方法重写基类。

请考虑以下事项:

class Base {
public:
    //virtual keyword allows method to be overriden
    virtual std::string Name() { return "Base Class"; }
    //virtual destructor needed for polymorphism otherwise it can lead to undefined behavior
    virtual ~Base(){} 
};

class Derived : public Base {
public:
    //optional keyword override signal the method has been overriden
    std::string Name() override { return "Derived Class"; }
};

class Derived2 : public Base {
public:
    std::string Name() override { return "Derived Class 2"; }
};

int main() {

    Base *object = new Derived();
    Base *object2 = new Derived2();
    Base *object3 = new Base();
    //collection of objects of type Base* which can hold any class of the family
    Base *collection[] = {object, object2, object3};

    for (auto &obj : collection) {//test print
        std::cout << obj->Name() << std::endl;
    }
}

正如注释所解释的,我可以有一个相同家族的不同对象的集合,当您调用name()时,方法调用将依赖于该对象。

输出:

Derived Class
Derived Class 2
Base Class

匿名用户

main修改为:

int main()
{
   Base* object = new Derived();

   std::cout << object->Name() << std::endl;
   return 0;
}

并添加3个缺失的“;” 在您的代码中,您将看到编写派生类,调用的方法名是派生对象的真正类型。

注意,虽然Name在基础上是虚拟的,但它也是派生的,即使你没有明确地说。

virtual允许在应用方法时使用对象的真实类型,因此即使对象也被声明为Base当Name为virtual时调用的版本是派生的真实类型之一

但是,如果删除编写基类的基中名称的定义中的virtual,因为对象被声明为基,那么被调用的方法就是在基上定义的名称。

结果将是相同的,在派生对象上添加virtual,但仍然在基上删除它,因为对于被声明为基的编译器对象,并且名称在基上不是虚拟的,调用时不考虑对象的实际类型

因此,具有:

#include <iostream>
#include <string>

class Base
{
  public:
    virtual std::string virtualName(){ return "Base Class";}
    std::string nonVirtualName(){ return "Base Class";}
};

class Derived : public Base
{
 public:
   std::string virtualName() {return "Derived Class";} // implicitely virtual
   std::string nonVirtualName(){ return "Base Class";}
};

int main()
{
   Base* object = new Derived();

   std::cout << object->virtualName() << std::endl;
   std::cout << object->nonVirtualName() << std::endl;

   return 0;
}

编译和执行:

bruno@bruno-XPS-8300:/tmp$ g++ -Wall a.cc
bruno@bruno-XPS-8300:/tmp$ ./a.out
Derived Class
Base Class
bruno@bruno-XPS-8300:/tmp$ 

注意,如果您在main的末尾添加delete object;,并且由于默认析构函数不是虚拟的,那么调用的析构函数正是nonVirtualName的Base析构函数,而不对derived进行任何操作。 在基上定义析构函数为虚拟是正确的做法,这意味着析构函数至少在派生上隐式为虚拟,从而允许在delete object;上执行两个析构函数