![]() |
|
Модераторы: bsa |
![]()
|
|
| efpies |
|
||||
|
Новичок Профиль Группа: Участник Сообщений: 43 Регистрация: 20.6.2009 Где: СПб Репутация: нет Всего: нет |
Здравствуйте.
Читал много чего по данной теме, но всё равно вопросы остаются, ибо нигде нет конкретики :( Есть класс вида
В функции происходит вот что:
Смотрим в отладчик: что ни ставь в параметрах setField (хоть const AnsiString&, хоть AnsiString), адреса у sample и a->field будут одинаковы. Но если изменить sample, изменится его указатель (?!), а a->field остаётся неизменным. Собственно, вопросы 1. Когда мы передаём по ссылке, мы передаём сам объект, а не его копию. Что будет, когда f() прекратит работу? Если sample уничтожится, уничтожится ли a->field? 2. Когда мы передаём const AnsiString&, передаётся сам объект, но недоступный для изменения. Происходит ли создание копии newField перед присваиванием, или a->field становится псевдонимом? 3. Как правильно передавать объект для последующего присваивания, чтобы уменьшить затраты? 4. Как правильно должна выглядеть функция sample = a->getField(), чтобы sample можно было бы изменять, не влияя на a->field, но, опять же, с минимальными затратами? AnsiString& getField() const, AnsiString getField() const или AnsiString& getField()? Спасибо. |
||||
|
|||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
Вам стоит отделить котлет от мух..
Да, передаете по ссылке, но зыбываете, что потом присваением изменяете содержимое другого объекта.. Добавлено через 43 секунды сомневаюсь |
|||
|
||||
| efpies |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 43 Регистрация: 20.6.2009 Где: СПб Репутация: нет Всего: нет |
Можете посоветовать что-то конкретное? ;)
|
|||
|
||||
| borisbn |
|
||||||||||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 4875 Регистрация: 6.2.2010 Где: Ростов-на-Дону Репутация: 21 Всего: 135 |
ни объект, и не копию, а именно ссылку. т.к. она константная, то изменять объект, на который она ссылается - нельзя. можно только получить копию объекта this->field = newField; // <- вот тут и делается копия leak памяти, потому, что A *a = new A; есть, а delete нет
присвоение - фактически и есть копия. но не через какой-то промежуточный объект, а сразу в a->field. a->field - не псевдоним, а самостоятельный объект, у которого изначально есть своё состояние, заданное в конструкторе AnsiString, а при присвоении оно (состояние) принимает значение от другого объекта (того, на который ссылается newField)
всё правильно сделал чтобы гарантировано нельзя было менять a->field - только AnsiString getField() const. можно ещё вернуть константную ссылку: const AnsiString & getField() const, но тут есть возможность нарваться на ошибку:
думаю ясно, что будет ? и ещё. Для разбора всех ситуаций с объектом, ссылками, указателями и т.п. советую вместо AnsiString использовать свой класс, в котором определить - конструктор по-умолчанию, - конструктор копирования, - оператор присвоения - деструктор в каждом из которых сделать тестовый вывод в консоль (типа cout << "A::A() this = " << this; или cout << "A::~A() this = " << this; Я понимаю, что твой A - неесть "боевой" класс, но просто обычно принято в начале описывать интерфейс (раздел public), а затем все private-члены, т.к. того, кому ты передаёшь свой класс, должен интересовать только интерфейс, а не как ты его реализовал. т.е. лучше так
Это сообщение отредактировал(а) borisbn - 27.3.2011, 22:01 -------------------- Женщины отличаются от программистов тем, что у них чары состоят из стрингов |
||||||||||||
|
|||||||||||||
| bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 85 Всего: 196 |
||||
|
||||
| xvr |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 35 Всего: 223 |
Вот тут вы заблуждаетесь - адреса самих объектов sample и a->field разные, а вот их (объектов) содержимое будет совпадать. AnsiString реализует так называемое Copy-On-Write хранение данных, т.е. пока вы не попытаетесь поменять значение строки AnsiString будет стараться избежать лишнего копирования данных. |
|||
|
||||
![]()
|
| Правила форума "C/C++: Для новичков" | |
|
|
Запрещается! 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Для новичков | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |