Посоветуйте реализацию: шаблон или класс?
От: NordWest Россия  
Дата: 21.03.12 14:33
Оценка:
Имеется набор классов для работы с файлами, в которых содержатся таблицы данных разного формата.
Подход для них общий. Открывается файл, построчно читается, каждая строчка обрабатывается соответствующим методом fromString и заполненные переменные нужного класса заносятся в список QList <> для дальнейшей работы.

class record
{
...
int fromString(QString str);
int toString(QString &str);
};

class recordList
{
QList <record*> recList;
recordList();
int init(QString fileName);
int save();
...
};


Как то так. Т.е. у таких классов есть явно общие черты, но и от типа record будут, например, особенности в init(). Подскажите, что тут логичнее применить.
Re: Посоветуйте реализацию: шаблон или класс?
От: ZegSoft Россия  
Дата: 21.03.12 15:06
Оценка:
Здравствуйте, NordWest, Вы писали:

NW>Имеется набор классов для работы с файлами, в которых содержатся таблицы данных разного формата.

NW>Подход для них общий. Открывается файл, построчно читается, каждая строчка обрабатывается соответствующим методом fromString и заполненные переменные нужного класса заносятся в список QList <> для дальнейшей работы.

NW>
NW>class record
NW>{
NW>...
NW>int fromString(QString str);
NW>int toString(QString &str);
NW>};

NW>class recordList
NW>{
NW>QList <record*> recList;
NW>recordList();
NW>int init(QString fileName);
NW>int save();
NW>...
NW>};
NW>


NW>Как то так. Т.е. у таких классов есть явно общие черты, но и от типа record будут, например, особенности в init(). Подскажите, что тут логичнее применить.


А почему нельзя и то и другое? То есть общий класс, но некоторые методы сделать шаблонными.
Re[2]: Посоветуйте реализацию: шаблон или класс?
От: NordWest Россия  
Дата: 21.03.12 15:47
Оценка:
Здравствуйте, ZegSoft, Вы писали:


ZS>А почему нельзя и то и другое? То есть общий класс, но некоторые методы сделать шаблонными.


Просто наследование я ещё как-то понимаю. Расширяю функциональность, перегружаю методы по необходимости. Но тут получается 2 класса. Один как переменная второго. Но в реальности будут использоваться потомки обоих. Тут либо нужно делать класс, считывающий строки, не наследуемым, но с указанием шаблона второго с пустыми определениями fromString,toString, которые перезагрузятся в потомках. Либо как? С наследованием я сталкивался, а вот шаблоны не применял, так что сложно перенести ситуацию в описаниях на данный конкретный пример.
Re[3]: Посоветуйте реализацию: шаблон или класс?
От: Valen  
Дата: 22.03.12 08:26
Оценка:
Здравствуйте, NordWest, Вы писали:


NW>Просто наследование я ещё как-то понимаю. Расширяю функциональность, перегружаю методы по необходимости. Но тут получается 2 класса. Один как переменная второго. Но в реальности будут использоваться потомки обоих. Тут либо нужно делать класс, считывающий строки, не наследуемым, но с указанием шаблона второго с пустыми определениями fromString,toString, которые перезагрузятся в потомках. Либо как? С наследованием я сталкивался, а вот шаблоны не применял, так что сложно перенести ситуацию в описаниях на данный конкретный пример.

Если архитектура подразумевает жесткое, заранее известное связывание потомков recordList с потомками record, то можно попробовать Bridge pattern. Определить интерфейсы в абстрактных классах, а в конкретном потомке recordList делать инстанс конкретного потомка record.

Если предполагается, что любые потомки recordList будут работать с любыми потомками record, то можно попробовать сделать recordList шаблонным, различие работы функции init вынести в отдельную шаблонную функцию и специализировать её для разных типов record. Если нужно одинаковое поведение этой функции для, например, всех потомков какого-то производного типа от record, то смотреть в сторону enable_if и type traits.
Re[4]: Посоветуйте реализацию: шаблон или класс?
От: NordWest Россия  
Дата: 22.03.12 09:53
Оценка:
Здравствуйте, Valen, Вы писали:

V>Если архитектура подразумевает жесткое, заранее известное связывание потомков recordList с потомками record, то можно попробовать Bridge pattern. Определить интерфейсы в абстрактных классах, а в конкретном потомке recordList делать инстанс конкретного потомка record.


Видимо ближе этот вариант. Т.е. у меня пары классов, наследующие от потомков базовый механизм. Но тут без template не обойтись, так как потомку recordList нужно указать потомка record.
Я сейчас сделал так, в других именах правда:

class tRecord
{
public:
    tRecord(){};
    int fromString(QString tStr){};
    int toString(QString &tStr){};
};

template <class tRecord>
class listFile
{
    QList <tRecord*> recList;
    QString fileName;
 public:
    listFile();
    int init(QString fname);
    int s2rec(QString tStr);
};

listFile::listFile()
{
}

int listFile::init(QString fname)
{
    ...
    return 0;
}

Потом определяю потомков:

class tlRecord : public tRecord
{
public:
        double exp;
        int Ntot;
        QString nam;
...
        tlRecord();
        int fromString(QString tStr);
        void toString(QString &tStr);
        tlRecord& operator=(const tlRecord &rhs);
};

class taskList : public listFile <tlRecord>
{

};


Но при определении в программе раздается ругань на все лады. Что не так?
Re[5]: Посоветуйте реализацию: шаблон или класс?
От: Valen  
Дата: 22.03.12 11:46
Оценка:
Здравствуйте, NordWest, Вы писали:

NW>Но при определении в программе раздается ругань на все лады. Что не так?

Какая именно ругань?
Re[6]: Посоветуйте реализацию: шаблон или класс?
От: NordWest Россия  
Дата: 22.03.12 12:16
Оценка:
Здравствуйте, Valen, Вы писали:

V>Здравствуйте, NordWest, Вы писали:


NW>>Но при определении в программе раздается ругань на все лады. Что не так?

V>Какая именно ругань?

Например:

ошибка: ‘template<class tRecord> class listFile’ used without template parameters


Если я определяю конструктор так:

template <class tRecord>
listFile<tRecord>::listFile()
{
}


То ошибка следующая:

ошибка: undefined reference to `listFile<tlRecord>::listFile()'


Ставлю "taskList <tlRecord> tList;":

ошибка: ‘taskList’ is not a template


Т.е. у меня конструктор не зависит от типа, как его не указывать? Там в объявлении что-то по другому указывается?
Re[7]: Посоветуйте реализацию: шаблон или класс?
От: Valen  
Дата: 22.03.12 13:57
Оценка:
Здравствуйте, NordWest, Вы писали:

NW>Здравствуйте, Valen, Вы писали:


V>>Здравствуйте, NordWest, Вы писали:


NW>>>Но при определении в программе раздается ругань на все лады. Что не так?

V>>Какая именно ругань?

NW>Т.е. у меня конструктор не зависит от типа, как его не указывать? Там в объявлении что-то по другому указывается?


Вот пример
http://ideone.com/dzTDC
Re[8]: Посоветуйте реализацию: шаблон или класс?
От: NordWest Россия  
Дата: 22.03.12 15:28
Оценка:
Здравствуйте, Valen, Вы писали:

V>Здравствуйте, NordWest, Вы писали:


NW>>Здравствуйте, Valen, Вы писали:


V>>>Здравствуйте, NordWest, Вы писали:


NW>>>>Но при определении в программе раздается ругань на все лады. Что не так?

V>>>Какая именно ругань?

NW>>Т.е. у меня конструктор не зависит от типа, как его не указывать? Там в объявлении что-то по другому указывается?


V>Вот пример

V>http://ideone.com/dzTDC

А как правильно функции-члены класса определять? Вот я, например, конструктор определяю:

template <typename tRecord>
listFile<tRecord>::listFile(){}

А при сборке ошибка:

undefined reference to `listFile<tlRecord>::listFile()'

Re[8]: Посоветуйте реализацию: шаблон или класс?
От: NordWest Россия  
Дата: 22.03.12 16:12
Оценка:
Здравствуйте, Valen, Вы писали:

V>Здравствуйте, NordWest, Вы писали:


NW>>Здравствуйте, Valen, Вы писали:


V>>>Здравствуйте, NordWest, Вы писали:


NW>>>>Но при определении в программе раздается ругань на все лады. Что не так?

V>>>Какая именно ругань?

NW>>Т.е. у меня конструктор не зависит от типа, как его не указывать? Там в объявлении что-то по другому указывается?


V>Вот пример

V>http://ideone.com/dzTDC
Да, чертовщина какая-то. Пример аналогичен и работает, а тут ничерта(
Re[9]: Посоветуйте реализацию: шаблон или класс?
От: Valen  
Дата: 22.03.12 17:53
Оценка:
Здравствуйте, NordWest, Вы писали:

NW>А как правильно функции-члены класса определять? Вот я, например, конструктор определяю:

Не нужно делать конструктор шаблонным.
http://ldmitrieva.blogspot.com/2010/11/blog-post_12.html
Re[10]: Посоветуйте реализацию: шаблон или класс?
От: NordWest Россия  
Дата: 22.03.12 18:57
Оценка:
Здравствуйте, Valen, Вы писали:
V>Не нужно делать конструктор шаблонным.
V>http://ldmitrieva.blogspot.com/2010/11/blog-post_12.html

Ага, сработало. А в темплате-классе вообще можно метод создать? Тот же init. Пока тоже с ошибкой:

prog.cpp: In function ‘int main()’:
prog.cpp:19: error: ‘int List<Record>::init() [with Record = RecordDer]’ is inaccessible
prog.cpp:32: error: within this context
prog.cpp:32: error: ‘List<RecordDer>’ is not an accessible base of ‘ListDer’

http://ideone.com/Z876Q
Re[11]: Посоветуйте реализацию: шаблон или класс?
От: Valen  
Дата: 22.03.12 21:18
Оценка:
Здравствуйте, NordWest, Вы писали:

NW>Здравствуйте, Valen, Вы писали:

V>>Не нужно делать конструктор шаблонным.
V>>http://ldmitrieva.blogspot.com/2010/11/blog-post_12.html

NW>Ага, сработало. А в темплате-классе вообще можно метод создать? Тот же init. Пока тоже с ошибкой:

Если нужно создать в шаблонном классе шаблонный метод, то это должно выглядеть так:

template<typename T>
class A
{
  template<typename U>
  int foo(){return 0;}
}

http://ideone.com/VLwyi

Нет смысла писать


template<typename T>
class A
{
  template<typename T>
  int foo(){return 0;}
}


т.к. метод foo() "уже шаблонный", т.е. зависит от параметра шаблона класса, т.к. разные параметры шаблона создают разные классы.
Re[12]: Посоветуйте реализацию: шаблон или класс?
От: NordWest Россия  
Дата: 12.05.12 13:29
Оценка:
Здравствуйте, Valen, Вы писали:

V>Если нужно создать в шаблонном классе шаблонный метод, то это должно выглядеть так:


V>
V>template<typename T>
V>class A
V>{
V>  template<typename U>
V>  int foo(){return 0;}
V>}

V>

V>http://ideone.com/VLwyi

V>Нет смысла писать



V>
V>template<typename T>
V>class A
V>{
V>  template<typename T>
V>  int foo(){return 0;}
V>}
V>


V>т.к. метод foo() "уже шаблонный", т.е. зависит от параметра шаблона класса, т.к. разные параметры шаблона создают разные классы.


Извиняюсь, оповещение об ответах не приходят, думал, что заглох вопрос и на другую работу переключился.
Так в том то и дело, что мне нужно определение метода init() в первом классе List. В нем используются функции-члены базового класса Record. Но получается, что для потомка ListDer он не хочет использовать данный метод с подстановкой потомка RecordDer. Только если переопределить init() в классе ListDer всё компилируется. Но теряется смысл. Толи синтаксически как-то неправильно написано, то ли хз.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.