2016-06-20 2 views
2

Я создал несколько различных объектов Dog и Cat внутри контейнера animalColl. Я пытаюсь настроить, как настроить поток файлов, который читается, чтобы, если объектом в контейнере является Cat, тогда используется catfile, а Dog использует файл dogfile. В настоящее время используется только тип animalType. Можно ли выбрать, какой поток файлов используется на основе типа объекта?C++ управление ifstream в контейнере с различными типами объектов

void Animal::load(std::string animalType) 
{ 
    std::string file = animalType + ".csv"; 
    std::ifstream lstream(file); 

    for (Animal *a : animalColl) 
    { 
     a->load(lstream); //uses one stream to read all the different objects in container 
    } 
} 
+0

Использовать 'dynamic_cast'? – Arunmu

ответ

2

К сожалению, я не уверен, почему вы вызываете нагрузку рекурсивно, поэтому я не могу дать точный ответ. Я думаю, что ответ, который вы ищете, будет использовать полиморфизм. Это простой пример:

animal.h

#ifndef ANIMAL_H 
#define ANIMAL_H 

#include <iostream> 
#include <string> 

class Animal 
{ 
public: 
    void load() 
    { 
     std::string fileName = this->getAnimalFilename() + ".csv"; 
     std::cout << "fileName = " << fileName << std::endl; 
    } 

protected: 
    virtual std::string getAnimalFilename() { return "Animal"; } 
}; 

#endif //ANIMAL_H 

dog.h

#ifndef DOG_H 
#define DOG_H 

#include <string> 
#include <iostream> 

class Dog : public Animal 
{ 

protected: 
    virtual std::string getAnimalFilename() { return "Dog"; } 
}; 

#endif //DOG_H 

cat.h

#ifndef CAT_H 
#define CAT_H 

#include <iostream> 
#include <string> 

class Cat : public Animal 
{ 

protected: 
    virtual std::string getAnimalFilename() { return "Cat"; } 
}; 

#endif //CAT_H 

И пример использования (обратите внимание, что вы должны использовать указатель на базовый класс, чтобы получить переопределяющую функцию полиморфизма, и вы ДОЛЖНЫ объявить функцию виртуальной, чтобы переопределить ее i n производный класс).

EDIT: приведенный ниже main.cpp был изменен для использования интеллектуальных указателей, поскольку он использовал необработанные указатели и вызвал утечку памяти, отмеченную @ArchbishopOfBanterbury.

main.cpp

#include <iostream> 
#include <vector> 
#include <string> 
#include <memory> 
#include "animal.h" 
#include "dog.h" 
#include "cat.h" 

int main(int argc, char *argv[]) 
{ 
    std::vector<std::unique_ptr<Animal>> animalColl; 
    animalColl.emplace_back(new Dog()); 
    animalColl.emplace_back(new Cat()); 
    animalColl.emplace_back(new Cat()); 
    animalColl.emplace_back(new Dog()); 
    for (auto &a : animalColl) { 
     a->load(); 
    } 

    return 0; 
} 

И выход:

fileName = Dog.csv 
fileName = Cat.csv 
fileName = Cat.csv 
fileName = Dog.csv 

Основная идея заключается в том, что вы используете ключевое слово виртуальный переопределить поведение при использовании указателя на базовый класс. Поэтому в моем примере getAnimalFilename переопределяется в классе Dog и Cat, чтобы вернуть правильную строку, а не передавать ее в функцию load(). Это помогает? Идем дальше и отвечаем на этот комментарий, и я постараюсь помочь как можно больше.

+0

У вас есть утечка памяти в 'main'. В этом случае используйте интеллектуальные указатели, а не необработанные указатели, т. Е. 'Std :: vector >' – ArchbishopOfBanterbury

+0

Спасибо, большой улов. Я обновил оригинальный пост. –

0

Есть несколько способов сделать это. Вы можете добавить элемент к имени класса называется и STRCMP это для проверки типа, например:

struct Animal { 
}; 
struct Dog : Animal { 
    string name = "Dog"; 
}; 
struct Cat : Animal { 
    string name = "Cat"; 
}; 

int main() { 
    Dog d; 
    if("Dog" == d.name) { 
     //do something 
    } 
    else if("Cat" == d.name) { 
     //do something else 
    } 
} 

Другой способ сделать это было бы, если вы знаете тип другого объекта, или готовы создать еще один объект типа Dog или Cat, вы можете сравнить эти типы, используя typeid (obj), например, используя те же структуры, что и выше:

int main(int argc, const char * argv[]) { 
    Dog d, o; 
    if (typeid(d) == typeid(o)) { 
     //do something 
    } 
    else { 
     //do something else 
    } 
} 
Смежные вопросы