powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Сакральный смысл передачи по ссылке &
25 сообщений из 38, страница 1 из 2
Сакральный смысл передачи по ссылке &
    #34436996
Фотография Zmeishe
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
class DB{
...
protected:
 QString Username;
public:
    QString & getUsername()
     {
	 return Username;
     };
...
}
/*Из help`a для QString определён оператор = */
QString & operator= ( const QString & s ) 
...

 1 )
QString User = db->getUsername(); // Компилируется без ошибок, но во время работы вместо User - лажа.

 2 )
QString User;
User = db->getUsername(); // Так нет лажи

 3 )
const QString & User = db->getUsername(); // Так тоже всё хорошо
В чём разница в порядке выполнения каждого из 3-х вариантов?
...
Рейтинг: 0 / 0
Сакральный смысл передачи по ссылке &
    #34437188
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Zmeishe пишет:
> Автор: "Zmeishe"
>
> class DB{
> ..
> protected:
> QString Username;
> public:
> QString & getUsername()
> {
> \t return Username;
> };
> ..
> }
> /*Из help`a для QString определён оператор = */
> QString & operator= ( const QString & s )
> ..
>
> *1*)
> QString User = db->getUsername(); // Компилируется без ошибок, но во время работы вместо User - лажа.
>
> *2*)
> QString User;
> User = db->getUsername(); // Так нет лажи
>
> *3*)
> const QString & User = db->getUsername(); // Так тоже всё хорошо
>
> В чём разница в порядке выполнения каждого из 3-х вариантов?


Здесь работает инициализация, а не присваивание. :

> QString User = db->getUsername(); // Компилируется без ошибок, но во время
работы вместо User - лажа.

QString для этого должен иметь конструктор копирования.


А здесь работает оператор присваивания.
> QString User;
> User = db->getUsername(); // Так нет лажи

Он там есть.

Здесь работает инициализация , но для типа
const QString& , а она встроена в язык. Поэтому плохо быть не может.

> *3*)
> const QString & User = db->getUsername(); // Так тоже всё хорошо
Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
Сакральный смысл передачи по ссылке &
    #34437193
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Zmeishe пишет:

> /*Из help`a для QString определён оператор = */
> QString & operator= ( const QString & s )

Странно, что в QString нет конструктора копирования, он обычно
должен быть, если есть operator = - это не навязывается языком,
но в хороших правилах это делать.
Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
Сакральный смысл передачи по ссылке &
    #34437238
Фотография Zmeishe
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivСтранно, что в QString нет конструктора копирования

Там есть вот такой конструктор QString( const QString & s )
Т.е. если я сделаю так:

QString User = QString(db->getUsername());
Лажа исчезнет?
Просто, проверить прямо сейчас не смогу.
...
Рейтинг: 0 / 0
Сакральный смысл передачи по ссылке &
    #34437339
Фотография Zmeishe
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я, теперь, понимаю так:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
//-- это правильно:
 1 ) QString & User = db->getUsername(); 
 2 ) const QString & User = db->getUsername(); 
 3 ) QString User;
    User = db->getUsername(); 

//-- это в КОРНЕ НЕ правильно:
QString User = db->getUsername(); 
А в чём, тогда разница между конструктором копирования и оператором присваивания - алгоритмически?
Можно на короткий примерчик взглянуть?

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
class A{
  A();
  A(const A & a);
  A & operator= (const A & a);

  int ParamA;
  short ParamB;
};

A::A()
{
  ParamA =  1 ;
  ParamB =  3 ;
}
Как будут выглядеть конструктор копирования и оператор присваивания?
...
Рейтинг: 0 / 0
Сакральный смысл передачи по ссылке &
    #34437406
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Zmeishe пишет:

> Там есть вот такой конструктор QString( const QString & s )
> Т.е. если я сделаю так:
>
> QString User = QString(db->getUsername());
> Лажа исчезнет?


Если такой конструктор есть ( это и есть конструктор копирования ),
то лажы быть не должно.

Так:
QString User = QString(db->getUsername());

делать можно, но бессмысленно. Ссылка на объект всегда может быть
преобразована к константной ссылке на объект.
Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
Сакральный смысл передачи по ссылке &
    #34437433
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Zmeishe пишет:

> //-- это правильно:
> *1*) QString & User = db->getUsername();
> *2*) const QString & User = db->getUsername();
> *3*) QString User;
> User = db->getUsername();
>
> //-- это в КОРНЕ НЕ правильно:
> QString User = db->getUsername();

Нет, это тоже правильно.

> А в чём, тогда разница между конструктором копирования и оператором
> присваивания - алгоритмически?

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

> Можно на короткий примерчик взглянуть?
>
> class A{
> A();
A(const A & a); // - это - конструктор копирования.
> A & operator= (const A & a); // - это - оператор присваивания.
>
> int ParamA;
> short ParamB;
> };
>
> A::A()
> {
> ParamA = *1*;
> ParamB = *3*;
> }
>
> Как будут выглядеть конструктор копирования и оператор присваивания?

Для этого класса ?

A::A(const A & right) : ParamA(right.ParamA), ParamB(right.ParamB)
{}

A & A::operator= (const A & a)
{
if ( this != &right )
{
ParamA = right.ParamA;
ParamB = right.ParamB;
}
return *this;
}


Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
Сакральный смысл передачи по ссылке &
    #34437485
Фотография blinded
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZiv
Zmeishe пишет:

> Там есть вот такой конструктор QString( const QString & s )
> Т.е. если я сделаю так:
>
> QString User = QString(db->getUsername());
> Лажа исчезнет?


Если такой конструктор есть ( это и есть конструктор копирования ),
то лажы быть не должно.

Так:
QString User = QString(db->getUsername());

делать можно, но бессмысленно. Ссылка на объект всегда может быть
преобразована к константной ссылке на объект.
Posted via ActualForum NNTP Server 1.4
Да просто запись
QString User = QString(db->getUsername());
это масло масленное. все равно неявно будет вызван конструктор копирования может проще написать явный вызов конструктора?
QString User(db->getUsername());
тут уж точно никто слоевольничать не будет.
Кстати а конструктор точно имеет такую сигнатуру QString( const QString&) может const всетаки нет?
...
Рейтинг: 0 / 0
Сакральный смысл передачи по ссылке &
    #34437624
Фотография Zmeishe
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivQString User = db->getUsername();

Нет, это тоже правильно.

Прикольно. Откуда тогда там лажа????

Вообще суть проблемы вот в чём.

Есть приложение. Пока было однопоточным - ну просто один главный процесс, всё работало стабильно длительное время.

Сделал многопоточным. Эпизодически стала выскакивать "Ошибка сегментирования" и аут.

Стал исследовать.
Поправил конструкторы некоторых классов наследников. Добавил к ним "(): конструктор родительского класса".
Ошибка стала выскакивать не эпизодически, а периодически и в одном и том же месте.Типа, локализовалась.
Там функция setValue(const QVariant & value);
Я туда делал setValue(db->getUsername()); и вот тут стал наступать АУТ, но иногда, а не всегда.

Прошёлся ещё по программе и удалил наследование в тех классах, где оно планировалось, но необходимость отпала.
Полный АУТ - валиться стала всегда на этом месте прямо с первой попытки.
делаю setValue(QVariant(db->getUsername()));
не валиться некоторое время, а потом опять.
делаю setValue( ( db->getUsername() ) );
валиться Эпизодически.

делаю
QString User = db->getUsername();

setValue(User);
валиться Эпизодически, но реже - раз в сутки.

Потом нашёл

я в конструкторе главного окна прописал (const char *)
а при передаче наляпал (QString()) вместо (QString().latin1())

и вот после этого исправления
вот тут QString User = db->getUsername(); началась лажа - полный АУТ. malloc() бла-бла-бла

переделал вот так
QString User;
User = db->getUsername();
сегодня с самого с ранья работает стабильно.

Ну вот типа так. Я вот думаю - может вся эта свистопляска из-за ещё какой-то бяки выше.
Но там уже фактически всё на пузе прополз - зацепиться даже не за что.

blindedКстати а конструктор точно имеет такую сигнатуру QString(const QString&) может const всетаки нет?
Может и нет. Проверю через час, когда снова в Linux перезагружусь. У меня нет Qt под Win.
...
Рейтинг: 0 / 0
Сакральный смысл передачи по ссылке &
    #34437996
maXmo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
может, ты старым гнусом компилишь?

Код: plaintext
1.
inline QString::QString(const QString &s) : d(s.d)
{ Q_ASSERT(&s != this); d->ref.ref(); }
...
Рейтинг: 0 / 0
Сакральный смысл передачи по ссылке &
    #34437997
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Zmeishe пишет:

> Стал исследовать.
> Поправил конструкторы некоторых классов наследников. Добавил к ним "():
> конструктор родительского класса".

Это зря. Конструктор базового класса и так вызывается. Всегда, даже
если не указан явно.

> Ошибка стала выскакивать не эпизодически, а периодически и в одном и том
> же месте.Типа, локализовалась.

Этого вообще быть не могло. Короче все пертрубации с кодом были
видимо зря. Кроме конечно удаления того, что и так было не нужно.

> Но там уже фактически всё на пузе прополз - зацепиться даже не за что.

Я думаю, как всегда, у тебя не используется CRT с поддержкой многопоточности.
Должна испльзоваться именно с поддержкой. Причем если есть разные С++-модули
или .DLL - они ВСЕ должны использовать именно CRT с поддержкой многопоточности.

> Кстати а конструктор точно имеет такую сигнатуру QString(const QString&)
> может const всетаки нет?

> Может и нет. Проверю через час, когда снова в Linux перезагружусь. У
> меня нет Qt под Win.

Не проверяй, должен быть QString(const QString&).
Но на самом деле это вообще не важно.
Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
Сакральный смысл передачи по ссылке &
    #34438112
Фотография Zmeishe
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maXmoможет, ты старым гнусом компилишь?gcc version 4.1.0 (SUSE Linux)


MasterZivЯ думаю, как всегда, у тебя не используется CRT с поддержкой многопоточности.Я как по Qt книге - включил в проект строчку CONFIG += qt warn_on release thread
CRT - это что? Я не в курсах.


MasterZivили .DLL - они ВСЕ должны использовать именно CRT с поддержкой многопоточностиу меня там только libgds.so
как узнать он с поддержкой или без?
...
Рейтинг: 0 / 0
Сакральный смысл передачи по ссылке &
    #34438219
maXmo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivЯ думаю, как всегда, у тебя не используется CRT с поддержкой многопоточности.маллос вроде в линух вшит чуть ли не в ядро :?
...
Рейтинг: 0 / 0
Сакральный смысл передачи по ссылке &
    #34438229
Фотография blinded
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Zmeishe maXmoможет, ты старым гнусом компилишь?gcc version 4.1.0 (SUSE Linux)


MasterZivЯ думаю, как всегда, у тебя не используется CRT с поддержкой многопоточности.Я как по Qt книге - включил в проект строчку CONFIG += qt warn_on release thread
CRT - это что? Я не в курсах.


MasterZivили .DLL - они ВСЕ должны использовать именно CRT с поддержкой многопоточностиу меня там только libgds.so
как узнать он с поддержкой или без?
Разговор слепых о слоне Один про Unix, другой про форточки
А узнать - взять исходники QString и посмотреть
...
Рейтинг: 0 / 0
Сакральный смысл передачи по ссылке &
    #34438266
maXmo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
blindedА узнать - взять исходники QString и посмотретьага и найти фигову кучу ифдефов
...
Рейтинг: 0 / 0
Сакральный смысл передачи по ссылке &
    #34438357
Фотография Zmeishe
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Выяснил про CRT и особую инициализацию глобальных переменных.

У меня там из глобольных переменных только QMutex - 3 штуки.
И эти мютексы не работают как в книге.
Работает только
QMutex g_mutex;
...

g_mutex.lock();
...
g_mutex.unlock();

А в книге ещё QWaitCondition используется

QMutex g_mutex;
QWaitCondition g_write;
...

g_mutex.lock();
g_write.wait(&g_mutex);
...
g_mutex.unlock();
g_write.wakeAll(); или g_write.wakeOne();

Больше не знаю куда копать.
...
Рейтинг: 0 / 0
Сакральный смысл передачи по ссылке &
    #34438523
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
blinded пишет:

> у меня там только libgds.so
> как узнать он с поддержкой или без?

Не знаю. Документацию прочитать.

> Разговор слепых о слоне Один про Unix, другой про форточки
> А узнать - взять исходники QString и посмотреть

А это не зависит от платформы. CRT - C runtime library.
В линухе называется (g)libc.
Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
Сакральный смысл передачи по ссылке &
    #34441029
Фотография Zmeishe
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Помедитировав над инициализацией и присваиванием, похоже, я нашёл причину всех проблем.


Раньше в конструкторах некоторых классов значения членам присваивал
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
class D;
class T;

class Q{
public:
  Q(D *d, T *t);

  D *p_d;
  T *p_t;
};

Q::Q(D *d, T *t)
{
  p_d = d;
  p_t = t;
}

Потом решил выпендриться и стал инициализировать
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
class D;
class T;

class Q{
public:
  Q(D *d, T *t);

  D *p_d;
  T *p_t;
};

Q::Q(D *d, T *t): p_d(d), p_t(t)
{
}

Насколько я понял - для этого важен не только порядок объявления их в классе, но место в классе, где их объявлять.
т.е. вот так

Код: plaintext
1.
2.
3.
4.
5.
6.
class Q{
public:
  D *p_d;
  T *p_t;

  Q(D *d, T *t);
};

Вернувшись к присваиванию, снова получил стабильную версию. И пока независящую от количества потоков - экспериментировал до 80-ти потоков одновременно.
Но сакрального смысла так и не понял. Хрен с ним. Лучшее - враг хорошего.(С)
...
Рейтинг: 0 / 0
Сакральный смысл передачи по ссылке &
    #34441050
Akh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Zmeishe
Насколько я понял - для этого важен не только порядок объявления их в классе, но место в классе, где их объявлять.
т.е. вот так

Код: plaintext
1.
2.
3.
4.
5.
6.
class Q{
public:
  D *p_d;
  T *p_t;

  Q(D *d, T *t);
};


Порядок объявлений в классе должен соответствовать порядку инициализации.
...
Рейтинг: 0 / 0
Сакральный смысл передачи по ссылке &
    #34441103
Фотография Zmeishe
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AkhПорядок объявлений в классе должен соответствовать порядку инициализации.
Об этом мне компилятор сразу сказал, накидав замечаний. Я исправил. И получил "блуждающую" ошибку. Там работает - тут нет, потом наоборот и без видимых причин.
А сейчас вернулся к прежнему варианту и получил стабильность снова.
...
Рейтинг: 0 / 0
Сакральный смысл передачи по ссылке &
    #34441141
Фотография Zmeishe
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В качестве предположения:

Если class рассматривать как struct, то
похоже, что для этих членов при инициализации ещё байтовое смещение от начала класса - имеет смысл.
А для присваивания - не имеет.
...
Рейтинг: 0 / 0
Сакральный смысл передачи по ссылке &
    #34441223
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Akh пишет:

> Насколько я понял - для этого важен не только порядок объявления их в
> классе, но место в классе, где их объявлять.
> т.е. вот так

> Порядок объявлений в классе должен соответствовать порядку инициализации.

Ничего он не должен. Инициализация производится в том порядке, в котором мемберы
объявлены в классе. А список инициализации в конструкторе может быть записан в
любом порядке, он вообще не важен.
Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
Сакральный смысл передачи по ссылке &
    #34441506
Akh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZiv
Akh пишет:

> Насколько я понял - для этого важен не только порядок объявления их в
> классе, но место в классе, где их объявлять.
> т.е. вот так

> Порядок объявлений в классе должен соответствовать порядку инициализации.

Ничего он не должен. Инициализация производится в том порядке, в котором мемберы
объявлены в классе. А список инициализации в конструкторе может быть записан в
любом порядке, он вообще не важен.

Мисье Мастер Зив считает хорошим стилем получать варнинги у компилятора?
...
Рейтинг: 0 / 0
Сакральный смысл передачи по ссылке &
    #34441694
Фотография blinded
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Akh MasterZiv
Akh пишет:

> Насколько я понял - для этого важен не только порядок объявления их в
> классе, но место в классе, где их объявлять.
> т.е. вот так

> Порядок объявлений в классе должен соответствовать порядку инициализации.

Ничего он не должен. Инициализация производится в том порядке, в котором мемберы
объявлены в классе. А список инициализации в конструкторе может быть записан в
любом порядке, он вообще не важен.

Мисье Мастер Зив считает хорошим стилем получать варнинги у компилятора?
Но тем не менее мисье абсолютно прав - члены класса инициализирутся в том порядке в котором определны в классе, порядок перечисления их после : не важен...А warning компилятора это как знак туда нельзя.( тем кто знает что делает можно )
...
Рейтинг: 0 / 0
Сакральный смысл передачи по ссылке &
    #34442002
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Akh пишет:

> Мисье Мастер Зив считает хорошим стилем получать варнинги у компилятора?

Да, а сейчас такие варнинги бывают, которых не избежать.
Типа "а не забыл ли ты в if-е написать сравнение вместо
присваивания" ?
Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
25 сообщений из 38, страница 1 из 2
Форумы / C++ [игнор отключен] [закрыт для гостей] / Сакральный смысл передачи по ссылке &
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]