将基类函数与派生类值一起使用

Using base class function with derived class values

本文关键字:一起 派生 基类 类函数      更新时间:2023-10-16

我在获取对象向量以打印派生类的名称而不是基类时遇到问题。

这些是我的课程

#include <vector>
#include <iostream>
using namespace std;
class Object
{
    string name;
public:
    string getName()
    {
        return name;
    }
};
class Flashlight : public Object
{
    string name = "Flashlight";
public:
    string getName();
};

这是我的主要内容,它有一个对象的向量,此时只需要打印出它们的名称。

int main()
{
    vector<Object> items;
    items.push_back(*new Flashlight);
    for(int i = 0; i < items.size(); i++)
    {
        cout << i+1 << " " << items.at(i).getName();
    }
}

现在,如果我在 Object 中为名称分配一些东西,它将打印它,但它不使用派生类值,我只希望它继承函数,然后使用它自己的值。我尝试在基类中实现该函数(但看到将来我可能会有很多这样的函数,这会导致大量冗余代码(,但这也不起作用。

不要在派生类中声明变量"name",而是将变量值初始化为该派生类的自定义值。另外,我建议您使getName方法成为虚拟方法。如果您只想输出名称,则也不需要重写派生类中的 getName 方法。

试试这个方式:

int main()
{
    vector<Object *> items;
    items.push_back(new Flashlight);
    for(int i = 0; i < items.size(); i++)
    {
        cout << i+1 << " " << items.at(i)->getName();
    }
}

同样如另一个答案所述,最好使用virtual方法阅读 这里.

更重要的是,您需要使用构造函数来设置变量name的值。你可以在这里阅读它们

您应该尝试以下方式:

class Object
{
private:
    string name;
public:
    Object() : name("Object")
    {}
    Object(string str) : name(str)
    {}
    string getName()
    {
        return name;
    }
};
class Flashlight : public Object
{
public:
    Flashlight() : Object("Flashlight")
    {}
    string getName();
};

您的代码有两个问题:

  1. getName()不是虚拟的。这意味着调用的实际函数是在编译时根据变量静态类型决定的。因此,如果您的变量属于 ObjectObject&Object* 的类型(或它们的任何const变体(,则将调用函数 Object::getName(),而不管您的变量引用或指向的对象的实际类型(动态类型(。
  2. 您有一个vector<Object>,这意味着存储在其中的所有对象都是 Object 类型。您可以尝试在其中放置一个Flashlight对象,但只有Object部分会被复制到矢量中。如果你在vector<>中需要多态性,你需要一个指针向量(或者更好的是智能指针(。

因此,您必须做两件事才能获得所需的行为:

  1. 将函数getName()声明为 virtual string getName()(偶数更好,virtual const string& getName() const(
  2. items声明为 vector<Object*> items(更好的是,使用适当的智能指针,例如 unique_ptr<> 而不是原始指针指针(