У меня возникают проблемы с получением вектора объектов для печати имени производного класса, а не базового класса.
Это мои занятия
#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, оно будет печатать это, но не используя значения производных классов, я просто хочу, чтобы он наследовал функцию, а затем использовал ее собственные значения. Я пробовал реализовать функцию в базовых классах (но, видя, что у меня может быть много таких в будущем, это приведет к большому количеству избыточного кода), но это тоже не сработает.
Попробуйте так:
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();
};
Вместо объявления переменной 'name' в производных классах инициализируйте значение переменных как пользовательское значение для этого производного класса. Также я бы предложил вам сделать метод getName виртуальным. Вам также не нужно переопределять метод getName в производных классах, если вы просто хотите вывести имя.
У вашего кода две проблемы:
getName()
не является виртуальным. Это означает, что указанная фактическая функция определяется во время компиляции на основе переменной статического типа. Таким образом, если переменная имеет тип Object
, Object&
или Object*
(или любой const
вариации на те), функции Object::getName()
будет называться, независимо от фактического типа объекта называется или указывает переменную (динамический тип).vector<Object>
, что означает, что все объекты, хранящиеся в нем, имеют тип Object
. Вы можете попытаться поместить в него объект Flashlight
, но только часть Object
будет скопирована в вектор. Если вам нужен полиморфизм в vector<>
, вам нужен вектор указателей (или даже лучше, умных указателей).Поэтому вам нужно сделать две вещи, чтобы добиться желаемого поведения:
getName()
как virtual string getName()
(еще лучше, virtual const string& getName() const
)items
как vector<Object*> items
items
vector<Object*> items
(еще лучше, используйте вместо этого необработанный указатель соответствующий интеллектуальный указатель, такой как unique_ptr<>
)