Russian Qt Forum

Qt => Общие вопросы => Тема начата: ilyagoo от Ноябрь 26, 2009, 09:48



Название: наследование и d_func()
Отправлено: ilyagoo от Ноябрь 26, 2009, 09:48
есть классы
Код:
class TClient: public QTcpSocket
class TServer: public QTcpServer
хочу переопределить виртуальную функцию
Код:
QTcpServer::incomingConnection()

а именно:

Код:
void QTcpServer::incomingConnection(int socketDescriptor)
{
#if defined (QTCPSERVER_DEBUG)
    qDebug("QTcpServer::incomingConnection(%i)", socketDescriptor);
#endif

    // создается новый сокет, здесь хотелось бы создавать нового TClient
    QTcpSocket *socket = new QTcpSocket(this);
    // установка дескриптора, полученного от системы останется
    socket->setSocketDescriptor(socketDescriptor);

    // добавление нового сокета в очередь соединений, откуда он будет вынут QTcpServer::nextPendingConnection()
    d_func()->pendingConnections.append(socket);
}

я так понимаю, d_func() - private член класса QTcpServer, и наследник ее вызвать не может... как с этим бороться? добавить-то в список клиента вроде как надо...


Название: Re: наследование и d_func()
Отправлено: Rcus от Ноябрь 26, 2009, 10:52
А зачем его добавлять в список? Ну если уж так хочется - создайте свою очередь и переопределите virtual bool hasPendingConnections () const и virtual QTcpSocket * nextPendingConnection () для сохранения функциональности.


Название: Re: наследование и d_func()
Отправлено: BRE от Ноябрь 26, 2009, 10:54
Не надо, если ты перекрываешь incomingConnection, то всю ответственность по созданию и удаления QTcpSocket берешь на себя.
Другой вариант это использовать:
void QTcpServer::newConnection ()   [signal]
и
QTcpSocket * QTcpServer::nextPendingConnection ()   [virtual]

тогда сам QTcpServer будет владельцем созданных QTcpSocket.


Название: Re: наследование и d_func()
Отправлено: ilyagoo от Ноябрь 26, 2009, 11:13
А зачем его добавлять в список? Ну если уж так хочется - создайте свою очередь и переопределите virtual bool hasPendingConnections () const и virtual QTcpSocket * nextPendingConnection () для сохранения функциональности.

как раз переопределение этих функций я и не планировал, т.к. если бы мне удалось добавить в список свой объект, nextPendingConnection() возвращал бы то, что нужно.

есть еще вариант: полностью переписать QTcpServer, он как раз небольшой :)

а создавать свой список - не айс, у QTcpServerPrivate уже есть один, и, сдается мне, что это не очень-то хороший тон...
может варианты все-таки есть?


Название: Re: наследование и d_func()
Отправлено: BRE от Ноябрь 26, 2009, 11:16
может варианты все-таки есть?
А чем не устраивает вариант с сигналом newConnection?


Название: Re: наследование и d_func()
Отправлено: ilyagoo от Ноябрь 26, 2009, 11:27
Цитировать
А чем не устраивает вариант с сигналом newConnection?

а что он мне даст? ведь к моменту его вызова QTcpSocket уже создан, а мне нужно иметь там своего TClient.

к предыдущему посту:
тем более, что в
Код:
void QTcpServerPrivate::readNotification()
есть строчка
Код:
        if (pendingConnections.count() >= maxConnections) {
значит я не должен использовать свой список


Название: Re: наследование и d_func()
Отправлено: BRE от Ноябрь 26, 2009, 11:35
а что он мне даст? ведь к моменту его вызова QTcpSocket уже создан, а мне нужно иметь там своего TClient.
Упс, это я упустил.  :)
Тогда, только наследованием.

А для чего ты хочешь сохранять все сокеты? Какая структура приложения?
Скажем, если этот сокет передается в отдельный поток, который обслуживает соединение с клиентом, проще будет самому удалять объект сокета в потоке при завершении связи.


Название: Re: наследование и d_func()
Отправлено: ilyagoo от Ноябрь 26, 2009, 11:42
Цитировать
А для чего ты хочешь сохранять все сокеты?
я и не хочу ;)

просто мне нужно подменить QTcpSocket у QTcpServer своим объектом


Название: Re: наследование и d_func()
Отправлено: BRE от Ноябрь 26, 2009, 11:45
я и не хочу ;)

просто мне нужно подменить QTcpSocket у QTcpServer своим объектом
Код
C++ (Qt)
void QTcpServer::incomingConnection(int socketDescriptor)
{
#if defined (QTCPSERVER_DEBUG)
   qDebug("QTcpServer::incomingConnection(%i)", socketDescriptor);
#endif
 
   // создается новый сокет, здесь хотелось бы создавать нового TClient
   QTcpSocket *socket = new QTcpSocket( 0 );
   // установка дескриптора, полученного от системы останется
   socket->setSocketDescriptor(socketDescriptor);
 
   emit clientConnected( socket );
 
// или
 
   TClientThread *thread = new TClientThread( socket );
   thread->start();
}
 


Название: Re: наследование и d_func()
Отправлено: ilyagoo от Ноябрь 26, 2009, 11:52
они же там хранятся, пока их не вынут:
Код:
QTcpSocket *QTcpServer::nextPendingConnection()
{
    Q_D(QTcpServer);
    if (d->pendingConnections.isEmpty())
        return 0;

    if (!d->socketEngine->isReadNotificationEnabled())
        d->socketEngine->setReadNotificationEnabled(true);

    return d->pendingConnections.takeFirst();
}
мы, кажется, друг друга не поняли :)


Название: Re: наследование и d_func()
Отправлено: ilyagoo от Ноябрь 26, 2009, 12:59
а есть ли какая-нибудь "технология", позволяющая создать, например, свой класс типа QTcpServer. да, вопрос корявый...
короче, я взял исходники сервера и тупо перебил все имена, тут-то линкер и накидал ошибок :(
типа таких:
Код:
1>netserver.obj : error LNK2019: unresolved external symbol "public: unsigned short __thiscall QAbstractSocketEngine::localPort(void)const " (?localPort@QAbstractSocketEngine@@QBEGXZ) referenced in function "public: bool __thiscall TNetServer::listen(class QHostAddress const &,unsigned short)" (?listen@TNetServer@@QAE_NABVQHostAddress@@G@Z)
1>qabstractsocket.obj : error LNK2001: unresolved external symbol "public: unsigned short __thiscall QAbstractSocketEngine::localPort(void)const " (?localPort@QAbstractSocketEngine@@QBEGXZ)

функция QAbstractSocketEngine::localPort() существует, но из QtNetwork4.dll она действительно не торчит. попробовал добавить в проект соответствующие исходники - толку мало. вот и интересуюсь "технологией". может кто-нибудь знает Qt глубже и сможет что-то посоветовать?


Название: Re: наследование и d_func()
Отправлено: BRE от Ноябрь 26, 2009, 13:11
они же там хранятся, пока их не вынут:
они туда кладутся методом incomingConnection, если ты его переопределил, то ничего и никуда класться не будет. pendingConnections будет пустым.


Название: Re: наследование и d_func()
Отправлено: ilyagoo от Ноябрь 26, 2009, 13:15
так и я про то же, я ведь искал как их туда добавить при переопределении incomingConnection(). похоже, никак :(
а по поводу "технологии" какие мысли?


Название: Re: наследование и d_func()
Отправлено: BRE от Ноябрь 26, 2009, 13:26
так и я про то же, я ведь искал как их туда добавить при переопределении incomingConnection(). похоже, никак :(
а по поводу "технологии" какие мысли?
А технология одна:
При подключении клиента, будет вызван incomingConnection, что в нем будет происходить это решать тебе: сохранять или нет список сокетов, передавать готовый сокет потоку или просто посылать сигнал.

Поищи по форуму, подобные темы несколько раз поднимались, были обсуждения с примерами кода и т.д.


Название: Re: наследование и d_func()
Отправлено: ilyagoo от Ноябрь 26, 2009, 13:45
да я не о том :D
я имел в виду "технологию" несколькими моими постами выше, это про Qt в общем


Название: Re: наследование и d_func()
Отправлено: lit-uriy от Ноябрь 26, 2009, 14:46
ilyagoo, тебе нужно инклюдить такие файлы как filename_p.h и делать по аналогии с тролями всякие объявления
внутренних структур данных, тогда тебе закрытые данные при наследовании станут доступны.


Название: Re: наследование и d_func()
Отправлено: ilyagoo от Ноябрь 26, 2009, 14:58
т.е. ты хочешь сказать, что:

Код:
class Base
{
    int m_Member;
};

class Derived : public Base
{
    void func() { m_Member = 0; }
};

при некотором включении заработает? не заработает.

видимо, я не так тебя понимаю. pimpl - это понятно, но как сварганить такой же класс - неясно...


Название: Re: наследование и d_func()
Отправлено: lit-uriy от Ноябрь 26, 2009, 15:01
нет я не хочу сказать, что твой пример сработает, используй макросы как в исходниках Qt, они позволяют двум классам (класс-интерфейс и класс-внутренности) общаться друг с другом


Название: Re: наследование и d_func()
Отправлено: kuzulis от Ноябрь 26, 2009, 15:03
http://techbase.kde.org/Policies/Library_Code_Policy#Shared_D-Pointers

оно?


Название: Re: наследование и d_func()
Отправлено: lit-uriy от Ноябрь 26, 2009, 15:05
Да вот есть темка свежая:
http://www.prog.org.ru/index.php?topic=11449
 их бы объеденить


Название: Re: наследование и d_func()
Отправлено: fuCtor от Ноябрь 26, 2009, 20:22
Вот тут статья на эту тему:
http://habrahabr.ru/blogs/qt_software/76248/