繁体   English   中英

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

[英]Using base class function with derived class values

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

这些是我的课

#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中的名称分配了一些内容,它将打印该内容,但不使用派生类的值,我只希望它继承该函数,然后使用它自己的值。 我已经尝试在基类中实现该功能(但是将来我可能会看到很多此类功能,这会导致很多冗余代码),但这也不起作用。

不用在派生类中声明变量“名称”,而是将变量值初始化为该派生类的自定义值。 另外,我建议您将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<>代替原始指针)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM