Модераторы: bsa
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Ссылки, Передача параметров и возврат объектов 
:(
    Опции темы
efpies
Дата 27.3.2011, 19:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 43
Регистрация: 20.6.2009
Где: СПб

Репутация: нет
Всего: нет



Здравствуйте.
Читал много чего по данной теме, но всё равно вопросы остаются, ибо нигде нет конкретики :(

Есть класс вида
Код

class A
{
   private : AnsiString field;

   public :
      AnsiString& getField();
      void setField(const AnsiString& newField) { this->field = newField; }
};


В функции происходит вот что:
Код

void f()
{
   AnsiString sample;
   sample = "sample";
   A *a = new A;
   a->setField(sample);
}


Смотрим в отладчик: что ни ставь в параметрах 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()?

Спасибо.
PM MAIL   Вверх
mes
Дата 27.3.2011, 19:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



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

Добавлено через 43 секунды
Цитата(efpies @  27.3.2011,  18:24 Найти цитируемый пост)
ибо нигде нет конкретики 

сомневаюсь  smile 


--------------------
PM MAIL WWW   Вверх
efpies
Дата 27.3.2011, 19:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 43
Регистрация: 20.6.2009
Где: СПб

Репутация: нет
Всего: нет



Можете посоветовать что-то конкретное? ;)
PM MAIL   Вверх
borisbn
Дата 27.3.2011, 21:51 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 21
Всего: 135



Цитата(efpies @  27.3.2011,  19:24 Найти цитируемый пост)
Когда мы передаём по ссылке, мы передаём сам объект, а не его копию.

ни объект, и не копию, а именно ссылку. т.к. она константная, то изменять объект, на который она ссылается - нельзя. можно только получить копию объекта
this->field = newField; // <- вот тут и делается копия

Цитата(efpies @  27.3.2011,  19:24 Найти цитируемый пост)
Что будет, когда f() прекратит работу?

leak памяти, потому, что A *a = new A; есть, а delete нет smile

Цитата(efpies @  27.3.2011,  19:24 Найти цитируемый пост)
Происходит ли создание копии newField перед присваиванием, или a->field становится псевдонимом?

присвоение - фактически и есть копия. но не через какой-то промежуточный объект, а сразу в a->field. a->field - не псевдоним, а самостоятельный объект, у которого изначально есть своё состояние, заданное в конструкторе AnsiString, а при присвоении оно (состояние) принимает значение от другого объекта (того, на который ссылается newField)

Цитата(efpies @  27.3.2011,  19:24 Найти цитируемый пост)
3. Как правильно передавать объект для последующего присваивания, чтобы уменьшить затраты?

Цитата(efpies @  27.3.2011,  19:24 Найти цитируемый пост)
void setField(const AnsiString& newField) { this->field = newField; }

всё правильно сделал

Цитата(efpies @  27.3.2011,  19:24 Найти цитируемый пост)
4. Как правильно должна выглядеть функция sample = a->getField(), чтобы sample можно было бы изменять, не влияя на a->field, но, опять же, с минимальными затратами? AnsiString& getField() const, AnsiString getField() const или AnsiString& getField()?

чтобы гарантировано нельзя было менять a->field - только AnsiString getField() const.
можно ещё вернуть константную ссылку: const AnsiString & getField() const, но тут есть возможность нарваться на ошибку:
Код

A * a = new A;
const AnsiString & refToField = a->getField();
delete a;
AnsiString s = refToField;

думаю ясно, что будет ?

и ещё. Для разбора всех ситуаций с объектом, ссылками, указателями и т.п. советую вместо AnsiString использовать свой класс, в котором определить
- конструктор по-умолчанию,
- конструктор копирования,
- оператор присвоения
- деструктор
в каждом из которых сделать тестовый вывод в консоль (типа cout << "A::A() this = " << this; или cout << "A::~A() this = " << this;

 smile 
Я понимаю, что твой A - неесть "боевой" класс, но просто обычно принято в начале описывать интерфейс (раздел public), а затем все private-члены, т.к. того, кому ты передаёшь свой класс, должен интересовать только интерфейс, а не как ты его реализовал.
т.е. лучше так
Код

class A {
   public :
      AnsiString& getField();
      void setField(const AnsiString& newField) { this->field = newField; }

   private : AnsiString field;
};


Это сообщение отредактировал(а) borisbn - 27.3.2011, 22:01


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
bsa
Дата 28.3.2011, 10:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 85
Всего: 196



PM   Вверх
xvr
Дата 28.3.2011, 16:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 35
Всего: 223



Цитата(efpies @  27.3.2011,  19:24 Найти цитируемый пост)
Смотрим в отладчик: что ни ставь в параметрах setField (хоть const AnsiString&, хоть AnsiString), адреса у sample и a->field будут одинаковы.

Вот тут вы заблуждаетесь - адреса самих объектов sample и a->field разные, а вот их (объектов) содержимое будет совпадать.  AnsiString реализует так называемое Copy-On-Write хранение данных, т.е. пока вы не попытаетесь поменять значение строки AnsiString будет стараться избежать лишнего копирования данных.

PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

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

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0528 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.