Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

С++ Создание массива объектов шаблонного класса; указатель на шаблонный объект стека

10K
16 января 2009 года
Frenzyk
41 / / 16.01.2009
Консольная программа, работаю в VS 2005

Есть шаблонный класс template<class T>class human, а также пораждённые от него классы, например template<class T>class emploee : public human<T>

Как можно создать массив, который мог бы хранить объекты этих классов с разными типами, например human<int> и human<char *>?

Для простых объектов сработал бы human * aray[4];, но не для шаблонных.

Кроме того есть класс стека с шаблонным содержанием

 
Код:
template<class T>class stack_element
{
protected:
    stack_element<T> * prev;
public:
    T content;

};


Как реализовать указатель, который может хранить адреса на объекты стека с разными типами данных. Например если у нас в первом объекте int, а во втором char, то второй должен содержать указатель на первый, который имеет тип данных int, а не char, как этот. Естественно данная конструкция нерабочая.
Или если это невозможно, то как можно по-другому связать стек с шаблоными данными?
87
17 января 2009 года
Kogrom
2.7K / / 02.02.2008
Например, так
Код:
struct people
{
    virtual ~people(){}
};

template<class T>
class human: public people
{
};

template<class T>
class emploee : public human<T>
{
};

human<int>* aray[4];

int main()
{
    human<int> hi;
    human<double> hd;
    emploee<int> ei;
   
    people* pp[3];
   
    pp[0] = &hi;
    pp[1] = &hd;
    pp[2] = &ei;
   
    return 0;
}
10K
17 января 2009 года
Frenzyk
41 / / 16.01.2009
Спасибо, помогло. Но теперь другая трабла:
Надо эти объекты из массива сохранять в файл

 
Код:
ofstream wfilez("emploees1.save");
wfilez.write((char *) pp[1], sizeof(people));


не работает, опять вместо people нужно указывать конкретный объект и его тип, например wfilez.write((char *) pp[1], sizeof(human<double>)) работает, но это естественно неприемлимо.
Можно писать в файл отдельно все переменные объекта, но тут проблема в другом:
Код:
template<class T>class human : public mammals
{
public:
   human(T, char *, char *, int); //инициализация параметров
   virtual void show_info(void); //показыввает параметры
   virtual void save(void); // сохраняет объект в файл
   //bool FileExist(const char*); //проверяет файл на существование
 //  friend class body;
protected:
    T ID;
    char name[32];
    char name2[32];
    int age;  

template<class T>human<T>::human(T id ,char *name, char *name2, int age)

{
    ID = id;
   strcpy(human::name, name);
   strcpy(human::name2, name2);
   human::age = age;

}
};


Тут всё хорошо, но до тех пор, пока T не char. И если он чар, то во-первых он char *, чтобы можно было присвоить как обычную переменную в конструкторе. И вот когда её надо записать в файл, то
wfile.write((char *) &ID, sizeof(T)); уже не сработает хотя бы потому, что sizeof(T) нужно умножить длинну строки.
Так что вот и вопрос: либо как целиком записывать объекты из массива, либо как реализовать корректно запись шаблонной переменной.

Кроме того потом еще из файла надо будет делать загрузку и как определить тип данных, записанный из шаблонной переменной и потом на основании этих данных создавать объект с соответствующим типом для загрузки - тоже вопрос.
87
17 января 2009 года
Kogrom
2.7K / / 02.02.2008
Цитата: Frenzyk

Можно писать в файл отдельно все переменные объекта, но тут проблема в другом...


Во первых проблема в смешении разных стилей программирования. Непонятно почему не использовать строки string из STL, если уж используются потоки?

Абстрактный класс родитель может содержать функцию со ссылкой на файловый поток, в который и будет писать данные. Что-то типа

virtual void Write(ofstream &f) = 0;

В наследниках эта функция будет заменяться но нужную типа

virtual void Write(ofstream &f){f << _val1 << _val2 << _val3 << ...; }


С чтением хуже - придется выдумывать какой-то формат записи для разных типов и парсер, который будет генерить соответствующие объекты.

10K
18 января 2009 года
Frenzyk
41 / / 16.01.2009
virtual void Write(ofstream &f){f << _val1 << _val2 << _val3 << ...; }

Да, я так примерно и сделал, но одно дело, когда _val1 - это просто переменная(int, float) и другое, когда это массив символов char(т.к. это шаблоннная переменная, то она может быть и тем и другим), точнее в моём случае указатель char * - нужен какой-то универсальный алгоритм, чтоб записывал и простые переменные и то, что находится по указателю на строку символов, или массив символов.
87
18 января 2009 года
Kogrom
2.7K / / 02.02.2008
Цитата: Frenzyk
Да, я так примерно и сделал, но одно дело, когда _val1 - это просто переменная(int, float) и другое, когда это массив символов char


В том то и дело, что примерно...

Ну да ладно, можно и по другому подойти, если использовать специализацию шаблонов функций. Примерно так:

Код:
template<class T> void Save(ofstream &f, T v)
{
    f.write(reinterpret_cast<char*>(&v), sizeof(v));
}

template<> void Save<const char*>(ofstream &f, const char* v)
{
    f.write(v, strlen(v));
}

template<class T>
class classA
{
    T _val;
    // ... другие параметры
public:
    void SetVal(const T &v){_val = v;}

    classA(T v):_val(v){}

    void Write(ofstream &f){Save(f, _val); /* ... */ }
};

int main()
{
    classA<const char*> a("testA\r\n");
    classA<int> b(567);
    classA<const char*> c("\r\ntestC");

    ofstream w("test.txt");
    a.Write(w);
    b.Write(w);
    c.Write(w);
    return 0;
}
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог