Использование функции базового класса со значениями производного класса

0

У меня возникают проблемы с получением вектора объектов для печати имени производного класса, а не базового класса.

Это мои занятия

#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, оно будет печатать это, но не используя значения производных классов, я просто хочу, чтобы он наследовал функцию, а затем использовал ее собственные значения. Я пробовал реализовать функцию в базовых классах (но, видя, что у меня может быть много таких в будущем, это приведет к большому количеству избыточного кода), но это тоже не сработает.

Теги:
c++11
inheritance

3 ответа

1
Лучший ответ

Попробуйте так:

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();
};
  • 0
    Это только часть проблемы. Переменная все еще не инициализирована должным образом.
  • 0
    Да, это сработало, я пытался использовать указатели ранее, но использовал их неправильно, спасибо за вашу помощь!
Показать ещё 1 комментарий
3

Вместо объявления переменной 'name' в производных классах инициализируйте значение переменных как пользовательское значение для этого производного класса. Также я бы предложил вам сделать метод getName виртуальным. Вам также не нужно переопределять метод getName в производных классах, если вы просто хотите вывести имя.

  • 0
    Это только часть проблемы. Коллекция Объекта, а не фонариков.
  • 0
    Что делать, если вы не переопределяете переменную имени в производном классе и инициализируете значение имени (определенного в базе) в производном классе, используя конструктор / установщик или что-то еще.
Показать ещё 1 комментарий
1

У вашего кода две проблемы:

  1. getName() не является виртуальным. Это означает, что указанная фактическая функция определяется во время компиляции на основе переменной статического типа. Таким образом, если переменная имеет тип Object, Object& или 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 items vector<Object*> items (еще лучше, используйте вместо этого необработанный указатель соответствующий интеллектуальный указатель, такой как unique_ptr<>)

Ещё вопросы

Сообщество Overcoder
Наверх
Меню