Russian Qt Forum

Программирование => С/C++ => Тема начата: thechicho от Январь 12, 2012, 16:33



Название: Пространство имен
Отправлено: thechicho от Январь 12, 2012, 16:33
Как использовать методы класса в другом классе без использования имени класса?
т.е. есть класс Functions;

так работает
Код
C++ (Qt)
int randInt = Functions::mt_rand(5,11);
как сделать, чтобы работало так
Код
C++ (Qt)
int randInt = mt_rand(5,11);

я пробовал в .h класса
Код
C++ (Qt)
namespace Ui {
class Functions;
}

но не канает.


Название: Re: Пространство имен
Отправлено: thechicho от Январь 12, 2012, 16:34
я не догоняю, как пространства имен работают. поясните, плиз, на моем примере, как мне сделать.


Название: Re: Пространство имен
Отправлено: kambala от Январь 12, 2012, 16:41
так, как ты хочешь, сделать нельзя. если метод (статический в данном случае) относится к классу, значит надо указывать имя класса. если вынесешь метод за класс, т.е. сделаешь обычной функцией, тогда имя не нужно указывать.

пространства имён просто заключают всё, что находится в них, в некую отдельную сущность. это позволяет использовать функции/классы/переменные/перечисления/и т.п. с одинаковыми именами. в литературе, та даже наверное и на вики, это всё прекрасно расписано.
элементарный пример:
Код
C++ (Qt)
namespace A {
int a;
void f();
}
namespace B {
int a;
void f();
}
 
// изменение разных переменных
A::a = 5;
B::a = 12;
// вызов разных функций
A::f();
B::f();


Название: Re: Пространство имен
Отправлено: Пантер от Январь 12, 2012, 16:42
Вынести функцию из класса.


Название: Re: Пространство имен
Отправлено: thechicho от Январь 12, 2012, 16:57
// пространства имён позволяют использовать функции/классы/переменные/перечисления/и т.п. с одинаковыми именами
понял, сенкс.

// если вынесешь метод за класс, т.е. сделаешь обычной функцией, тогда имя не нужно указывать.
приведи, плиз, пример. я не понимаю как и куда вынести, т.е. где прописать.

просто, у меня есть ~10 функций, кот. я постоянно пользуюсь в проектах.
мне надоело их каждый раз переносить в новый проект, поэтому я решил сделать 1 класс, его подключить и использовать эти функции.
тут наследование тогда получается...

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


Название: Re: Пространство имен
Отправлено: Пантер от Январь 12, 2012, 17:02
Нахрена класс? Просто выносишь функции в отдельный h/cpp, который и подключаешь.


Название: Re: Пространство имен
Отправлено: thechicho от Январь 12, 2012, 17:11
сделал, множественное наследование (+свой класс) и все вроде работает, как и хотел.

// Нахрена класс? Просто выносишь функции в отдельный h/cpp, который и подключаешь.
а это тема, кстати) чот я не подумал, что так работать будет, ща попробую.


Название: Re: Пространство имен
Отправлено: andrew.k от Январь 12, 2012, 21:29
сделал, множественное наследование (+свой класс) и все вроде работает, как и хотел.

// Нахрена класс? Просто выносишь функции в отдельный h/cpp, который и подключаешь.
а это тема, кстати) чот я не подумал, что так работать будет, ща попробую.
"А слона то я и не приметил" (с) И.А. Крылов


Название: Re: Пространство имен
Отправлено: Пантер от Январь 12, 2012, 21:29
сделал, множественное наследование (+свой класс) и все вроде работает, как и хотел.

// Нахрена класс? Просто выносишь функции в отдельный h/cpp, который и подключаешь.
а это тема, кстати) чот я не подумал, что так работать будет, ща попробую.
Только оберни все функции в namespace на всякий случай. У меня так во всех проектах core.cpp + core.h, где глобальные константы и функции.


Название: Re: Пространство имен
Отправлено: thechicho от Январь 12, 2012, 22:13
//"А слона то я и не приметил" (с) И.А. Крылов
Воды слонам. А нам лишь бы работало.

Пантер, залей плиз эти файлы, я гляну как у тебя все сделано. + может какие функции пригодятся потом.
просто я через класс все уже сделал, вроде ровно работает пока. наследую его, чтобы использовать. класс в отдельных файлах, почти как у тебя получилось.


Название: Re: Пространство имен
Отправлено: andrew.k от Январь 12, 2012, 22:25
//"А слона то я и не приметил" (с) И.А. Крылов
Воды слонам. А нам лишь бы работало.

Пантер, залей плиз эти файлы, я гляну как у тебя все сделано. + может какие функции пригодятся потом.
просто я через класс все уже сделал, вроде ровно работает пока. наследую его, чтобы использовать. класс в отдельных файлах, почти как у тебя получилось.
Это жесть. Представляешь если все так будут делать, что будет?


Название: Re: Пространство имен
Отправлено: popper от Январь 12, 2012, 22:55
Если есть набор постоянно используемых функций, то напрашивается решение собрать их в отдельную библиотеку. Видимо автор сообщения пришел в С++ из явы, если возникают трудности с объявлением функции вне класса. Предлагаю найти исходники любой библиотеки на С и изучить их структуру. Возможно, будет полезно почитать про ключевое слово
Код:
extern "C" 


Название: Re: Пространство имен
Отправлено: thechicho от Январь 13, 2012, 01:15
// Это жесть. Представляешь если все так будут делать, что будет?
работать будет


Название: Re: Пространство имен
Отправлено: thechicho от Январь 13, 2012, 01:16
у меня там 10+ функций, какая библиотека)


Название: Re: Пространство имен
Отправлено: andrew.k от Январь 13, 2012, 01:26
// Это жесть. Представляешь если все так будут делать, что будет?
работать будет
А представляешь список инклудов в большом проекте.
И он дополнится таким же списком наследуемых классов.
Раздуется класс, который будет все это использовать, код станет нечитаемым.
у меня там 10+ функций, какая библиотека)
Тем более какие сложности переделать эту глупость в namespace?

PS но я опять не забыл, что ты все делаешь для себя и для своих. Поэтому оставь лучше внутри класса)


Название: Re: Пространство имен
Отправлено: thechicho от Январь 13, 2012, 02:04
дак работает и пое :D

// переделать эту глупость в namespace
а вот попрошу не хамить! :D я эту глупость вымучивал хз сколько времени)

переделаю, как-нибудь)
если Пантер выложит, и я реально увижу, что игра стоит свеч, тогда пораньше, если нет, тогда когда-нибудь)
кароче, сенкс всем за помощь


Название: Re: Пространство имен
Отправлено: kambala от Январь 13, 2012, 04:04
открой любой немаленький опенсорс проект и посмотри


Название: Re: Пространство имен
Отправлено: Пантер от Январь 13, 2012, 09:25
Лови core.(cpp/h) из одного проекта.


Название: Re: Пространство имен
Отправлено: thechicho от Январь 13, 2012, 12:36
сенкс, Пантер.

а это норма одну строчку в функцию переводить? чот я не понял зачем :)

Код
C++ (Qt)
void writeSocket (QTcpSocket *socket, const QString &data)
{
socket->write ( (data + "\n").toUtf8 ());
}

вот несколько моих функций для работы с сетью

Код
C++ (Qt)
void Functions::GET(QNetworkAccessManager &qnam, bool redirect, bool readAnswer, bool showHeaders)
{
   QEventLoop loopGet;
   int badProxyCount=0;
 
   request.setRawHeader("Content-Type", QByteArray());
 
   REPEATGET:
 
   reply = qnam.get(request);
   //if (proxyType == "NoUseProxy")
//    QTimer timer;
//    timer.start(30000);
//    connect(&timer, SIGNAL(timeout()), &loopGet, SLOT(quit()));
 
   QObject::connect(reply, SIGNAL(finished()), &loopGet, SLOT(quit()));
   loopGet.exec();
 
   //if (proxyType == "NoUseProxy")
//    if (timer.isActive())
//        timer.stop();
 
   reply->deleteLater();
 
   if (reply->error()) {
       qDebug() << reply->errorString() << reply->error();
 
       if (badProxyCount<3) {
           badProxyCount++;
           qDebug() << "badProxyCountGet: " << badProxyCount;
           goto REPEATGET;
       }
   }
 
   if (showHeaders) HTTPHEADERS(reply);
 
   if (redirect) {
       REDIRECT(qnam, readAnswer, showHeaders);
       return;
   }
 
   if (readAnswer) {
       if (reply->rawHeader("Content-Encoding").contains("gzip")) { //if (gzip)
           answer = uncompress(reply->readAll());
       } else {
           answer = reply->readAll();
       }
   }
 
   lastUrl = reply->url().toString();
}
 
void Functions::POST(QNetworkAccessManager &qnam, bool redirect, bool readAnswer, bool showHeaders)
{
   QEventLoop loopPost;
   int badProxyCount=0;
 
   REPEATPOST:
 
   request.setRawHeader("Content-Type", "application/x-www-form-urlencoded");
 
   reply = qnam.post(request, postData);
 
   //if (proxyType == "NoUseProxy")
//    QTimer timer;
//    timer.start(30000);
//    connect(&timer, SIGNAL(timeout()), &loopPost, SLOT(quit()));
 
   QObject::connect(reply, SIGNAL(finished()), &loopPost, SLOT(quit()));
   loopPost.exec();
 
   //if (proxyType == "NoUseProxy")
//    if (timer.isActive())
//        timer.stop();
 
   reply->deleteLater();
 
   if (reply->error()) {
       qDebug() << reply->errorString() << reply->error();
 
       if (badProxyCount<3) {
           badProxyCount++;
           qDebug() << "badProxyCountPost: " << badProxyCount;
           goto REPEATPOST;
       }
   }
 
   if (showHeaders) HTTPHEADERS(reply);
 
   if (redirect) {
       REDIRECT(qnam, readAnswer, showHeaders);
       return;
   }
 
   if (readAnswer) {
       if (reply->rawHeader("Content-Encoding").contains("gzip")) { //if (gzip)
           answer = uncompress(reply->readAll());
       } else {
           answer = reply->readAll();
       }
   }
 
   lastUrl = reply->url().toString();
 
}
 
void Functions::HTTPHEADERS(QNetworkReply *reply)
{
   if (!SHOWHEADERS) return;
 
   qDebug() << endl << reply->url();
   qDebug() << "Request headers:  ";
   QList<QByteArray> reqHeaders = reply->request().rawHeaderList();
   //QList<QByteArray> reqHeaders = request.rawHeaderList();
   foreach (QByteArray reqName, reqHeaders)
   {
       QByteArray reqValue = reply->request().rawHeader(reqName);
       //QByteArray reqValue = request.rawHeader(reqName);
       qDebug() << reqName << ": " << reqValue;
   }
   qDebug() << "Reply headers:  ";
   QList<QByteArray> reqHeadersReply = reply->rawHeaderList();
   foreach( QByteArray reqName, reqHeadersReply )
   {
       QByteArray reqValue = reply->rawHeader( reqName );
       qDebug() << reqName << ": " << reqValue;
   }
}
 
void Functions::CLEARREQUEST(QNetworkRequest request)
{
   //QList<QByteArray> reqHeaders = reply->request().rawHeaderList();
   QList<QByteArray> reqHeaders = request.rawHeaderList();
   foreach (QByteArray reqName, reqHeaders)
   {
       //QByteArray reqValue = reply->request().rawHeader(reqName);
       QByteArray reqValue = request.rawHeader(reqName);
       //qDebug() << reqName << ": " << reqValue;
       request.setRawHeader(reqName, QByteArray());
   }
 
}

.h
Код
C++ (Qt)
 
public:
 
void GET(QNetworkAccessManager&, bool redirect = false, bool readAnswer = false, bool showHeaders = false);
   void POST(QNetworkAccessManager&, bool redirect = false, bool readAnswer = false, bool showHeaders = false);
   void REDIRECT(QNetworkAccessManager&, bool readAnswer = false, bool showHeaders = false);
   void HTTPHEADERS(QNetworkReply*);
   void CLEARREQUEST(QNetworkRequest);
 
QNetworkReply *reply;
   QNetworkRequest request;
   QString answer;
   QString lastUrl;
   QByteArray postData;
 
   bool SHOWHEADERS;

я не силен еще в этом, но если из класса эту байду вынесу, тогда reply и request, будут не видимы же в функциях? т.е. их придется передавать в параметрах, а это каждый раз тупо их писать. потом, если после функции захочу из reply чо-нить прочитать, надо будет функцию делать, кот. будет репли возвращать, т.е. еще лишний код каждый раз вбивать...


Название: Re: Пространство имен
Отправлено: Пантер от Январь 13, 2012, 12:45
Цитировать
а это норма одну строчку в функцию переводить? чот я не понял зачем
Вполне нормально. Чтобы не раскидывать по всему коду этот перевод строки. А если, в последствии, протокол немного изменится, придется только в одном месте подправить. Функция, скорее всего, заинлайнится и не будет стратиться время на ее вызов.

В твоем случае паршивастенько все сделано, но сделай так
QString GET (..............)
И используй свой QNetworkReply в функции.


Название: Re: Пространство имен
Отправлено: thechicho от Январь 13, 2012, 12:47
а что именно у меня может привести и к чему?


Название: Re: Пространство имен
Отправлено: Пантер от Январь 13, 2012, 12:48
а что именно у меня может привести и к чему?
Если у тебя функция и так синхронна, то и возвращай из нее значение.


Название: Re: Пространство имен
Отправлено: thechicho от Январь 13, 2012, 12:52
если возвращать, тогда логичней было бы сделать так
QNetworkReply* GET (..............)

но, я так делать не стал, т.к. влом стало лишние телодвижения делать,
т.е. каждый раз писать код считывания ответа, если он понадобится.

я подумал проще сделать глобальную переменную и туда читать по ходу перезаписывать, если понадобится...

к каким косякам может привести мой подход?


Название: Re: Пространство имен
Отправлено: Пантер от Январь 13, 2012, 13:20
К непониманию со стороны колег. ;)


Название: Re: Пространство имен
Отправлено: kambala от Январь 13, 2012, 13:35
goto вместо цикла - это здорово


Название: Re: Пространство имен
Отправлено: Пантер от Январь 13, 2012, 13:39
goto вместо цикла - это здорово
Охтыжблин. А я до туда не дочитал. Зачет, чё.


Название: Re: Пространство имен
Отправлено: thechicho от Январь 13, 2012, 13:43
я читал как-то холивар на эту тему.
но мне кажется куда удобнее goto воткнуть, чем в цикл оборачивать.
тем более у меня goto работает по принципу, если нужный результат не получен, попробуй еще раз (сразу или через определенное время).
я не вижу причин, фигачить все в цикл, когда с goto все делается гораздо удобнее.

вы грите, руководствуясь своим подходом к написанию кода.
вы лучше по делу скажите, как это может повлиять на саму работу программы: производительность, стабильность.
понятность кода 100% у меня :P


Название: Re: Пространство имен
Отправлено: Пантер от Январь 13, 2012, 13:52
В одном потоке вызывается GET, а в другом POST. ;)
Не пиши так, даже для себя. GOTO никогда не нужен. А если и нужен, значит у тебя мысль не туда пошла.


Название: Re: Пространство имен
Отправлено: andrew.k от Январь 13, 2012, 13:55
Это влияет на понимание кода другим человеком или тобой же самим немного погодя)
Вот сиди ищи где ты воткнул эту метку. Какой может быть холивар?

Я знаю только один удобный случай применения goto. Это выход из вложенных циклов.
Это очень соблазнительно использовать его.

вы грите, руководствуясь своим подходом к написанию кода.
вы лучше по делу скажите, как это может повлиять на саму работу программы: производительность, стабильность.
понятность кода 100% у меня :P
Это общепринятые подходы.
Я уж было подумал, что ты стал беспокоиться о своем коде, что завел такую тему. А нет все в порядке)


Название: Re: Пространство имен
Отправлено: kambala от Январь 13, 2012, 13:57
куда прозрачнее там будет использовать рекурсию. конечно, для этого придётся немного переписать код.

я бывает использую goto для выхода из вложенных циклов (о, выше как раз написали об этом :) ), чтобы не разводить булевские переменные. в питоне с этим дело обстоит поприятнее ;)


Название: Re: Пространство имен
Отправлено: thechicho от Январь 13, 2012, 15:32
// В одном потоке вызывается GET, а в другом POST.
вот это будет эпик фейл...
но разве для каждого потока не будут созданы свои экземпляры класса Functions...

у меня ща так сделано

Код
C++ (Qt)
class BlaBlaThread : public QThread, public Functions
{
   Q_OBJECT
 
public:

я думал, что для каждого потока будет свой объект Functions, соответственно, общих данных не будет...

ведь так? :o


Название: Re: Пространство имен
Отправлено: Пантер от Январь 13, 2012, 15:34
Ох, ппц. Учи ООП. Нахрена тут множественное наследование?


Название: Re: Пространство имен
Отправлено: thechicho от Январь 13, 2012, 15:35
чтобы можно было использовать функции без всяких приставок (класса, namespace и тп)


Название: Re: Пространство имен
Отправлено: Пантер от Январь 13, 2012, 15:38
facepalm.jpg (http://t0.gstatic.com/images?q=tbn:ANd9GcQb1d3g0kDHorVbeK3J9DRYZyulILKJnFb_jJPaO02CSYz6jMbzvw)

Множественное наследование нужно только тогда, когда оно оправдано. Лично мне еще ни разу не пришлось им пользоваться.


Название: Re: Пространство имен
Отправлено: kambala от Январь 13, 2012, 15:41
у тебя что ли оплата работы обратно пропорциональна количеству символов?


Название: Re: Пространство имен
Отправлено: thechicho от Январь 13, 2012, 15:42
а чо метку искать-то, в нескольких строчках.

// Это общепринятые подходы.
анархия мать порядка.

// Я уж было подумал, что ты стал беспокоиться о своем коде, что завел такую тему. А нет все в порядке)
харе палить кантору 8)

// куда прозрачнее там будет использовать рекурсию. конечно, для этого придётся немного переписать код
это хде?О_о
у меня там рекурсия только на переход по редиректу.
или ты чо имеешь в виду.

а насчет вложенных циклов... я до них еще не дорос, т.к. я хз чо за циклы такие ::) break; решает все проблемы :D


Название: Re: Пространство имен
Отправлено: thechicho от Январь 13, 2012, 15:48
// Множественное наследование нужно только тогда, когда оно оправдано. Лично мне еще ни разу не пришлось им пользоваться
а чем оно плохо в данном случае?
если я правильно понимаю, для каждого потока будет создан свой экземпляр с функциями, т.е. глабальные переменные класса Functions будут в каждом потоке свои адреса иметь. как-то так... короче работать должно. если я все правильно понимаю.

а если делать без множественного наследования, тогда придется переписывать функции, делать их без глобальных переменных. соответственно придется в каждую функцию пихать каждый раз реквест и репли. возвращаться будет репли. после функции его разбирать, если надо. это лишний код каждый раз.
зачем? если как я сделал, удобнее гораздо. ток будет работать или нет в многопоточном режиме, еще не тестил :D

// у тебя что ли оплата работы обратно пропорциональна количеству символов?
кто бы меня взял то еще на работу прогером :D
я не работаю "на дядю". я продаю софт и услуги пока что.
а так, если бы я в команде работал, разумеется использовал бы "общепринятые нормы" по мере знаний своих неглубоких :D


Название: Re: Пространство имен
Отправлено: thechicho от Январь 13, 2012, 15:53
// facepalm.jpg
этот круче http://kolobok.us/smiles/light_skin/facepalm.gif
кстати, добавь лучше колобков вместо этих смайлов.

а то тока один прикольный -  :D
ну этот еще ничо так - :o


Название: Re: Пространство имен
Отправлено: thechicho от Январь 13, 2012, 15:55
зацените аву :D


Название: Re: Пространство имен
Отправлено: Пантер от Январь 13, 2012, 15:55
Цитировать
а чем оно плохо в данном случае?
Да тем, что у тебя идет лишняя завязка. Вот зачем множественное наследование, если можно сделать так:
Код:
class BlaBlaThread : public QThread
{
    Q_OBJECT
 
private:
Functions functions_;
Это тоже хреново, но получше твоего варианта.


Название: Re: Пространство имен
Отправлено: mutineer от Январь 13, 2012, 16:02
а так, если бы я в команде работал, разумеется использовал бы "общепринятые нормы" по мере знаний своих неглубоких :D

Откуда ж ты эти нормы возьмешь, если не используешь их в коде своем?


Название: Re: Пространство имен
Отправлено: thechicho от Январь 13, 2012, 16:03
// Вот зачем множественное наследование, если можно сделать так
так сделать нельзя, все методы и свойства вываливаются из области выдимости. т.е. вылазит куча ошибок. надо тогда к каждой функции приписывать объект.

// Это тоже хреново, но получше твоего варианта
я так и делал сначала, но грю, только с именем объекта видно.
поэтому методом тыка отнаследовал, и все заработало :D

и чем хреново то? :)
это как-то скажется на производительности, стабильности работы проги?


Название: Re: Пространство имен
Отправлено: thechicho от Январь 13, 2012, 16:06
// Откуда ж ты эти нормы возьмешь, если не используешь их в коде своем?

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


Название: Re: Пространство имен
Отправлено: andrew.k от Январь 13, 2012, 16:14
// Откуда ж ты эти нормы возьмешь, если не используешь их в коде своем?

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


Название: Re: Пространство имен
Отправлено: thechicho от Январь 13, 2012, 16:22
если обломится такое счастье и кто-то меня возьмет на работу программером ("будь проклят тот день, когда... я нанял его на работу" (с) потенциальный работодатель :) )

я не начну красиво и технологичено писать код.
я буду писать, как того потребуют реалии.

приказ - написать красиво и технологично.
будет написано красиво и технологично.
приказ - написать быстро и шобы работало
будет написано быстро и будет работать.

я себе отдаю приказы второго плана :D
вот как-то так.
andrew.k, хватит выдумывать то, чего нет :P


Название: Re: Пространство имен
Отправлено: kambala от Январь 13, 2012, 16:36
с таким подходом у страны нет будущего


Название: Re: Пространство имен
Отправлено: mutineer от Январь 13, 2012, 16:37
Да ладно вам. Ну жалко человеку символов. Может у него винт маленький и дописывание неймспейса к каждому вызову не дает файл сохранить. Или печатает медленно...


Название: Re: Пространство имен
Отправлено: thechicho от Январь 13, 2012, 16:47
// с таким подходом у страны нет будущего
совершенно несравнимые вещи.
а так если о политике... у рашки будущее есть, а вот у вас - не уверен. зря за независимость голосовали. жили же дружно, а ща как враги, газ поделить не могут.

mutineer, ни то, и не другое. объясни, какое я получу преимущество, если сделаю как ты советуешь?


Название: Re: Пространство имен
Отправлено: mutineer от Январь 13, 2012, 16:49
mutineer, ни то, и не другое. объясни, какое я получу преимущество, если сделаю как ты советуешь?

Ммм... Для начала надо бы узнать как я советую;)


Название: Re: Пространство имен
Отправлено: kambala от Январь 13, 2012, 17:06
// с таким подходом у страны нет будущего
совершенно несравнимые вещи.
а так если о политике...
сравнимые. вряд ли у тебя другие подходы в других вещах. а о политике я ни слова не сказал.

а вот представь, что ты идёшь на собеседование на программиста, и тебя просят показать примеры своих работ - там уже слова "та это я для себя так писал - абы работало" не прокатят.