Russian Qt Forum

Qt => Общие вопросы => Тема начата: ammaximus от Декабрь 03, 2014, 11:30



Название: Шаблоны против friend
Отправлено: ammaximus от Декабрь 03, 2014, 11:30
Продолжаю работать по этой теме http://www.prog.org.ru/topic_27878_0.html (http://www.prog.org.ru/topic_27878_0.html)

Задача - сделать шаблон, который представляет в общей памяти простой массив примитивных типов. Функции:
0. Автоподруб к разделяемой памяти - в конструктор передается только размер (в элементах) и строка ключа.
1. Доступ по индексу
2. Очистка содержимого
3. Вывод содержимого в QDebug
4. Де/сериализация QDataStream
5. Шаблон можно вставлять в библиотеки. Т.е. шаблон может использоваться как базовый класс для класса, который SHARED в dll. Тут могут возникнуть проблемы, если у шаблона не все расшарено?

Проблемы возникли на этапах 4 и 3.

Код:
#include <QLocalSocket>
#include <QSharedMemory>
#include <QDebug>

// 1. Simple type array version
template <typename T>
class ShmSimple{
protected:
    int maximumSize;
    QString name;
    QSharedMemory shm;
    QLocalSocket ls;

    T* begin;
public:
    ShmSimple(QString key, int maxSize)
        :maximumSize(maxSize), name(key), shm(key), begin(0)
    {
        if(!shm.attach()){
            qDebug() << "Create";
            if (!shm.create(sizeof(T)*maximumSize))
                qDebug() << "CREATE FALLS";
            else{
                begin = static_cast<T*>(shm.data());
                qDebug() << "Result:" << begin;
                clear();
            }
        }
    }

    ~ShmSimple(){
        qDebug() << "Destructor start";
    }

    void clear()
    {
        int *p=begin;
        int c=0;
        qDebug() << "ClearContent:" << maximumSize;
        while (c++ < maximumSize){
            *p++=0;
        }
    }

    T& operator[](int pos)
    {
        return begin[pos];
    }


//    friend QDebug operator<< (QDebug qdb, const T &array);

    //    friend QDataStream& operator<< (QDataStream &write, const GeoAngle &angle);
    //    friend QDataStream& operator>> (QDataStream &read,  GeoAngle &angle);
};

//template <typename T>
//QDebug operator<<(QDebug qdb, T &array)
//{
//    int *p = static_cast<int*>(array.shm.data());
//    int c=0;
//    qdb.nospace();
//    qdb << "SHMARRAY<"<<array.name<<"> ";
//    while (c++ < array.maximumSize){
//        qdb << *p++;
//    }
//    return qdb.maybeSpace();
//}

По общепринятой системе операторы для QDebug и QDatastream пишутся снаружи, а в классе объявляются как друзья. Проблема в том, что компилятор не понимает, что закомментированный кусок и есть тот самый друг и ругается на protected доступ.

P.S. Понятно, что можно сделать через публичные методы, но этот класс - первый шаг, дальше будут сложные классы, аналоги QMap и т.д., где такое не прокатит.


Название: Re: Шаблоны против friend
Отправлено: m_ax от Декабрь 03, 2014, 12:28
Потому что объявлен friend не правильно..

Код
C++ (Qt)
template <class R>
friend QDebug operator<< (QDebug qdb, const ShmSimple<R> & array);
 
 
...
 
template <class R>
QDebug operator<< (QDebug qdb, const ShmSimple<R> & array)
{
...
}
 
 


Название: Re: Шаблоны против friend
Отправлено: ammaximus от Декабрь 03, 2014, 13:24
 :D :D :D
точно, спасибо