Russian Qt Forum

Qt => Вопросы новичков => Тема начата: vanchester от Февраль 11, 2014, 13:34



Название: Работа с csv файлами по интерфейсу, совместимому с libxl
Отправлено: vanchester от Февраль 11, 2014, 13:34
У меня есть программа, работающая с xls файлами, используя библиотеку libxl. Программа просто читает файл и выводит его данные в табличку QTableWidget.
Сейчас возникла задача сделать поддержку csv файлов. Хотелось бы просто добавить класс с методами для работы с csv, при этом ничего не меняя в существующем коде. Как-то так:

Код:
Book* book;
if (excelfileName.endsWith(".xlsx")) {
    book = xlCreateXMLBook();
} else if (excelfileName.endsWith(".xls")) {
    book = xlCreateBook();
} else {
    book = new CSVBook();
}

book->load(excelfileName.toLocal8Bit().data());
sheet = book->getSheet(0);
sheet->readStr(0, 0)

Саму логику для работы непосредственно с csv написать не проблема, но вот с типизацией в с++ я совсем слаб.
Подскажите, пожалуйста, какой здесь применим паттерн, как двигаться дальше? как сделать CSVBook совместимым с Book?


Название: Re: Работа с csv файлами по интерфейсу, совместимому с libxl
Отправлено: kambala от Февраль 11, 2014, 13:37
надо класс CSVBook унаследовать от класса Book. наследование поддерживается в большинстве языков программирования.
Код
C++ (Qt)
class CSVBook : public Book
{
...
};


Название: Re: Работа с csv файлами по интерфейсу, совместимому с libxl
Отправлено: Johnik от Февраль 11, 2014, 13:41
> какой здесь применим паттерн
Паттерн Factory.
Делаешь базовым интерфейсом - интерфейс Book, выделяешь в него общие методы.
Далее в каждом потомке реализуешь логику конкретную для каждого случая.


Название: Re: Работа с csv файлами по интерфейсу, совместимому с libxl
Отправлено: vanchester от Февраль 11, 2014, 14:23
Book в данном случае является структурой:

libxl.h
Код:
typedef IBookT<char> Book;

IBookT.h
Код:
struct IBookT
{
        virtual             bool XLAPIENTRY load(const TCHAR* filename) = 0;
        <...>
}
extern "C" XLAPI libxl::IBookT<char>* XLAPIENTRY xlCreateBookA();
<...>

Как мне правильнее унаследоваться?
Если делаю
Код:
class CSVBook: public libxl::Book
{
};
в строчке book = new CSVBook(); получаю ошибку cannot allocate an object of abstract type 'CSVBook'.


Название: Re: Работа с csv файлами по интерфейсу, совместимому с libxl
Отправлено: kambala от Февраль 11, 2014, 14:51
тебе нужно написать реализацию всех чистых виртуальных функций чтобы объект класса CSVBook можно было создать. в твоей структуре есть как минимум один такой метод (который ты и указал).


Название: Re: Работа с csv файлами по интерфейсу, совместимому с libxl
Отправлено: vanchester от Февраль 12, 2014, 06:15
Спасибо за подсказки, удалось сделать то, что хотелось.
Столкнулся с несколькими проблемными местами в реализации (которых при наличии базовых знаний не было бы  ::) ):
1. Нужно переопределять все виртуальные методы, иначе класс считается абстрактным. Сам класс объявил так:
Код:
template<class TCHAR>
class csvbook: public libxl::IBookT<char>
{
<...>
}
2. Т.к. используются шаблоны, вся реализация методов должна находиться в том же файле, в котором они объявлены
3. Создание экземляра пришлось вынести в шаблонную функцию
Код:
template<class TCHAR>
csvbook<TCHAR>* csvCreateBook()
{
    csvbook<TCHAR>* book;
    book = new csvbook<TCHAR>;
    return book;
}
и создавать сам экземляр таким способом:
Код:
book = csvCreateBook<char>();


Название: Re: Работа с csv файлами по интерфейсу, совместимому с libxl
Отправлено: kambala от Февраль 12, 2014, 11:36
и в чем проблемы? :)


Название: Re: Работа с csv файлами по интерфейсу, совместимому с libxl
Отправлено: vanchester от Февраль 12, 2014, 12:49
Так я их описал вместе с моими вариантами решения. На случай, если у кого-то еще вопрос по этой задаче возникнет


Название: Re: Работа с csv файлами по интерфейсу, совместимому с libxl
Отправлено: vanchester от Февраль 14, 2014, 07:38
Все же рано я радовался :(
На linux все собирается нормально. При попытке собрать на windows получаю ошибки типа:

Код:
csvbook.h:91: ошибка: conflicting type attributes specified for 'bool CSVBook<TCHAR>::load(const TCHAR*) [with TCHAR = char]'
 bool CSVBook<TCHAR>::load(const TCHAR* filename)
      ^

Есть мысли, куда теперь копать?

попробовал поправить в своих новых классах код
Код:
template<class TCHAR>
class csvbook: public libxl::IBookT<char>
на
Код:
template<class TCHAR>
class csvbook: public libxl::IBookT<TCHAR>

не помогло. Не помогла и попытка:
Код:
typedef char TCHAR;


Название: Re: Работа с csv файлами по интерфейсу, совместимому с libxl
Отправлено: vanchester от Февраль 14, 2014, 11:48
Вопрос решен. Проблема была в потерянном XLAPIENTRY в моем классе