LINUX.ORG.RU

.at() Qt

 , ,


0

2

Доброго времени суток. Такой вопрос: функция

const T &QList::at(int i) const
возвращает адрес, судя по всему. Почему тогда
QString str = stringData.at(i);
работает, а
const QString* p_str = stringData.at(i);
ругается на конвертацию типов?



Последнее исправление: Rot1 (всего исправлений: 1)

возвращает адрес, судя по всему

ты уверен, что уже стоит писать на Qt? Она возвращает константную ссылку на символ.

former_anonymous ★★★
()
Последнее исправление: former_anonymous (всего исправлений: 1)

Она возвращает ссылку (она то является адресом, но несколько «скрытым»). Первый вариант копирует объект, на который она указывает, а второму надо добавить &:

const QString* p_str = &stringData.at(i);

xaizek ★★★★★
()
Последнее исправление: xaizek (всего исправлений: 1)
Ответ на: комментарий от xaizek

То, что первый вариант- копирование- понятно. Что значит «скрытый адрес»? В сигнатуре стоит знак амперсанда.

const int a = 5; const int* b = &a
. Не является идентичным примером?

Rot1
() автор топика
Ответ на: комментарий от xaizek

Или знак & в возврате значения функции роли в присвоении не играет?

Rot1
() автор топика
Ответ на: комментарий от former_anonymous

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

Rot1
() автор топика
Ответ на: комментарий от Rot1

Имя типа с амперсандом в конце - ссылка. Имя типа со звездочкой в конце - указатель. Амперсанд перед объектом (или ссылкой на него) возвращает его указатель. Советую изучить хотя бы самые основы C++.

equeim ★★
()
Последнее исправление: equeim (всего исправлений: 2)
Ответ на: комментарий от Rot1

верно, строка, моя ошибка. Но суть остаётся. Это банальности С++, которые ты не изучил, а уже берёшься за Qt. Я просто советую.

Или знак & в возврате значения функции роли в присвоении не играет?

играет. Можно написать так:

const QString &s = list.at(0);


Мы создали ссылку на строку по индексу 0.

QString s = list.at(0);


В классическом С++ мы бы создали копию объекта по индексу 0. НО в Qt есть хитрая техника, называемая implicit sharing. В данном примере мы создали копию объекта, который разделяет внутренние данные (низкоуровневое представление строки в формате UCS) с объектом по индексу 0. При попытке модификации объекта s произойдёт отделение (detach) его разделяемой копии внутренних данных (COW, copy on write).

Видишь сколько всякой ерунды проистекает всего лишь от одной строки кода?

former_anonymous ★★★
()
Ответ на: комментарий от equeim
// копия строки под индексом i
QString str = mStringData.at(i);

// константная ссылка на строку под индексом i
const QString& str = mStringData.at(i);

// константный указатель на строку под индексом i
const QString* str = &(mStringData.at(i));

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

equeim ★★
()
Ответ на: комментарий от equeim

это я знаю. А ты хочешь сказать, что понятия адреса в с++ нет? Может тебе нужно изучить хотя бы самые основы? По-твоему, вывод int a; std::cout<<&a<<std::endl; -указатель? Смотри-ка, амперсанд же перед идентификатором стоит... Лучше бы на вопрос ответил, а не пытался стоить из себя кого-то, кем не являешься

Rot1
() автор топика
Ответ на: комментарий от former_anonymous

Ты оказывается даже и сигнатуру не прочитал? Функция возвращает const QString &. А судя из твоей цитаты, «const QString &s = list.at(0);», и из того, что возврат & имеет значение в присвоении, ты ссылке присваиваешь ссылку, гениально. Банальности с++ как раз ты и не знаешь

Rot1
() автор топика
Ответ на: комментарий от former_anonymous

В классическом С++ мы бы создали копию объекта по индексу 0.

Это тоже копирование объекта, как он устроен изнутри - дело десятое, и к основам понимания копирования/ссылок/указателей отношения не имеющее.

equeim ★★
()
Ответ на: комментарий от Rot1

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

equeim ★★
()
Ответ на: комментарий от Rot1

Функция QList::at(int) возвращает константную ссылку. В втором примере мы значению переменной str, имеющей тип const QString& (константная ссылка на QString) присваиваем значение ссылки, которую возвращает QList::at(int).

equeim ★★
()
Ответ на: комментарий от Rot1

Не является идентичным примером?

Нет, амперсанд в типах и выражениях — это два разных амперсанда.

Что значит «скрытый адрес»?

Это указатель, но с ограничениями. Арифметика недоступна, обязательно надо инициализировать, изменить значение нельзя. Любое обращение к объекту типа Type &a вроде a.stuff эквивалентно (*pa).stuff, где Type *pa. Это такая более безопасная версия указателя.

xaizek ★★★★★
()
Ответ на: комментарий от equeim

где я вообще там про указатель писал, омг? Зачем проводить операцию взятия адреса, если функция его возвращает, алло, ты читал вообще, что я пишу?

Rot1
() автор топика
Ответ на: комментарий от Rot1

Еще раз, функция QList::at(int) возвращает ссылку, а не указатель.

В втором примере мы значению переменной str, имеющей тип const QString& (константная ссылка на QString) присваиваем значение ссылки, которую возвращает QList::at(int). Т.е. ссылка str указывает на строку, находящуюся в stringData под индексом i.

В третьем примере мы значению переменной str, имеющей тип const QString* (константный указатель на QString), присваиваем значение указателя, полученного операцией взятия адреса от ссылки, возвращаемой QList::at(int). str так же указывает на строку, находящуюся в stringData под индексом i, но теперь это указатель, а не ссылка.

equeim ★★
()
Последнее исправление: equeim (всего исправлений: 1)
Ответ на: комментарий от Rot1

где я вообще там про указатель писал, омг? Зачем проводить операцию взятия адреса, если функция его возвращает, алло, ты читал вообще, что я пишу?

Лол, а ты читал что пишут тебе?

В чем разница:

int a = 1;
int& b = a;
int* c = &a;

Stil ★★★★★
()
Ответ на: комментарий от xaizek

ну если она возвращает ссылку, тогда зачем к ней подписывать еще «&», чтоб присвоить указателю? Ссылка ведь и представляет из себя адрес, который нужен указателю

Rot1
() автор топика
Ответ на: комментарий от Rot1

Потому что ссылка не может автоматически преобразовываться в указатель.

equeim ★★
()
Ответ на: комментарий от Stil

лол, а ты читал шапку? функция возвращает уже &a, тогда получается вариант int* c = stringData.at(i), который неверен

Rot1
() автор топика
Ответ на: комментарий от Rot1

Он неверен, потому что ты указателю присваиваешь ссылку. В C++ так делать нельзя.

equeim ★★
()
Ответ на: комментарий от Rot1

Да не адрес* она возвращает! А ссылку. Вот тебе «на поразмыслить»:

struct Data { int i; } d;

// возвращаем указатель, взятие адреса происходи явно,
// с помощью оператора &
Data * getPtr() { return &d; }

// возвращаем копию обьекта
Data getCopy() { return d; }

// возвращаем ссылку, конвертация между ссылками и 
// реальными обьектами (значениями) происходит неявно
Data & getRef() { return d; }

Так же на этапе обучения С++ (собственно как у тебя) можно считать, что ссылка — это просто другое имя того же обьекта (значения).

В случае возврата ссылки вызывающий решает копировать ли обьект:

Data dcopy = getRef(); // копируем
Data & dref = getRef(); // не копируем
Data * dptr = & getRef(); // не копируем

* Гусары, молчать, тут человек основ С++ не понимает.

KennyMinigun ★★★★★
()
Последнее исправление: KennyMinigun (всего исправлений: 1)

Забавно, когда человек задаёт глупые вопросы (что вполне естественно, когда начинаешь изучать новую технологию), но на ответы на них агрится и пытается убедить всех, что это не он написал некорректный код, а собеседник написал бред. Когда удастся убедить в этом и компилятор, можно констатировать успех.

Softwayer ★★
()
Ответ на: комментарий от KennyMinigun

Спасибо, теперь понятно

Rot1
() автор топика
Ответ на: комментарий от Softwayer

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

Rot1
() автор топика
Ответ на: комментарий от Rot1
// defines 
int get_value();
int &get_reference();
const int &get_const_reference();
int *get_pointer();

// usage
int a = get_value();
int b = get_reference();
int &rb = get_reference();
const int &crb = get_const_reference();
int b1 = get_const_reference();
int *c = int *get_pointer();

Используется так, и никак иначе. Стоит запомнить.

kachsheev ★★★
()
Последнее исправление: kachsheev (всего исправлений: 2)

Иди читай про разницу ссылок и указателей в C++. И, пожалуйста, не надо агриться, когда люди говорят тебе, в чём проблема. Не всяк амперсанд в C++ является операцией взятия адреса. Это основы C++ - лучше вот Прата почитай, Страуструпа иль чего там ещё. Потом уже лезь в Qt.

zamazan4ik ★★
()
Ответ на: комментарий от Rot1

спрашиваешь об одном, а тебе пишут совсем о другом

Это ты путаешься в терминах и не можешь понять, что тебе пишут по теме, ещё и агришься на это, некрасиво.

unC0Rr ★★★★★
()

Не адрес, а ссылку. Это С++, детка!

hibou ★★★★★
()

опять ты!

вот я вижу твой пост и уже знаю, что внутри будет какая-то хрень.

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

i36_zubov
()
Ответ на: опять ты! от i36_zubov

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

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

QString x;
QString& y = x; //y указывает на х
QString* z = &y; //z тоже указывает на х

это как «адрес того, на что указывает y»

i36_zubov
()
Ответ на: комментарий от zamazan4ik

Подобные комментарии, которых выше есть ещё несколько штук от разных пользователей, больше смахивают на спесивое желание похорохориться. Причём как правило, граждане пишущие в таком стиле сами «плавают» в обсуждаемом вопросе.

anonymous
()

возвращает адрес, судя по всему. Почему тогда

иди липпмана читай, убоище

Sectoid ★★★★★
()
Ответ на: комментарий от anonymous

То есть Вы хотите сказать, что не стоит ознакамливаться с азами? И сразу лезть куда-то в дебри надо? Зачем? Выше ему отписали, где он ошибается. Он аггрится. И что с такими делать? Новичками были все, и здесь нет ничего зазорного. Надо просто слушать и анализировать, что тебе говорят люди, которые наверное чуточку больше разбираются в данном вопросе.

Что касается меня, то я с горем пополам выучил некоторые различия ссылок и указателей в цепепе.

zamazan4ik ★★
()
Ответ на: комментарий от Rot1

В сигнатуре стоит знак амперсанда

T* QList::at(int i)

вот так был бы указатель на объект типа T, а

const T &QList::at(int i) const
возвращает ссылку на объект типа T.

anonymous
()
Ответ на: комментарий от anonymous

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

const T &QList::at(int i) const
const T& QList::at(int i) const

одно и то же.

anonymous
()
Ответ на: комментарий от Rot1

Выпишете ему -20 уже

И отправьте читать Страуструпа :c

BruteForce ★★★
()
Ответ на: комментарий от BruteForce

.at() Qt (комментарий)

Ну вот, ещё один пожаловал, желающий самоутвердится возвысившись над ближним.

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

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.