Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.80/5: Рейтинг темы: голосов - 5, средняя оценка - 4.80
70 / 70 / 35
Регистрация: 06.07.2016
Сообщений: 415

Присваивание объектов одного типа между собой и передача объекта в функцию по значению

01.02.2017, 20:27. Показов 1135. Ответов 9
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
При первом знакомстве с С++ усиленно не могу понять вот такие моменты :
1. Имеем вот такой код :
Кликните здесь для просмотра всего текста
C++
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 use_string
{
    char *string;
public :
    use_string(char *input_string) { string = new char[std::strlen(input_string) + 1]; std::strcpy(string, input_string);}
    ~use_string() { delete(string); }
    void get_new_string(char *new_string){ delete(string); string = new char[std::strlen(new_string) + 1]; std::strcpy(string, new_string);}
    char *show_string() { return string; }
};
 
 
int main()
{
    use_string str1("Ola"), str2("Halo");
 
    str2 = str1;
    std::cout << str2.show_string() << std::endl;
    std::cout << str1.show_string() << std::endl;
    str2.get_new_string("Milk");
    std::cout << str2.show_string() << std::endl;
    std::cout << str1.show_string() << std::endl;
    system("pause");
    return 0;
}

Мы присвоили объекты между собой и в итоге указатель из объекта str2 начал указывать на строку из объекта str1. После этого мы получаем в str2 новую строку, стирая старую (Тут первая ошибка - теперь указатель из объекта str1 начинает указывать в "никуда"). Смотрим на содержимое str2 - все хорошо. Смотрим на содержимое str1 - вот она ошибка. Далее,при выходе из программы еще получается, что мы забыли очистить память , на которую первоначально указывал указатель из объекта str2. Об этом нам сразу напомнят, выбив исключение.
Так вот, тут два вопроса - правильно ли я все понимаю. (Буду раз увидеть новые подробности или более полный разбор, так как хочется реально понимать,что же там происходит) и второе,почему это так ужасно реализовано? Почему просто перебрасывается указатель из str2 на содержимое из str1? Почему это не происходит именно с удалением текущего значения str2,выделения новой памяти и копирования туда строки из str1? (Ну,не только строки, чего бы там вообще не было). Больше всего убивает именно этот "переброс" указателя.
2. Теперь имеем вот такой код :
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <iostream>
 
class test
{
    int *pointer;
public : 
    test() { std::cout << "Constructor works!" << std::endl;  pointer = new int[1];}
    ~test() { std::cout << "Destructor works!" << std::endl; delete pointer; }
    void set(int value) { *pointer = value; }
    int get() { return *pointer;}
};
 
 
void function(test _test);
int main()
{
 
    test _test;
 
    _test.set(10);
    std::cout << _test.get() << std::endl;
    function(_test);
    std::cout << _test.get() << std::endl;
 
    return 0;
}
 
void function(test _test)
{
 
}

Определили объект, конструктором выделили память под одно значение типа int. Деструктором будем ее очищать. Создаем объект такого типа. Кидаем его в функцию. Передаем именно по значению. То есть должна создаться копия объекта. Так почему при выходе из функции деструктор чистит адрес именно самого объекта? Ведь должна создаваться временная локальная копия? Пусть там с ней происходит что угодно. Какое право эта функция имеет трогать адрес ,который принадлежит объекту,переданному туда по значению? И почему она вообще его трогает? Или же здесь создается локальная копия, которая при этом получает еще и валидные текущие адреса полей?
Очень непонятные для меня моменты, особенно после С,где всё было логично и связно.
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
01.02.2017, 20:27
Ответы с готовыми решениями:

Передача объекта типа TStringGrid в функцию в Embarcadero C++
Здравствуйте. Недавно начал изучать embarcadero c++ builder и столкнулся с проблемой: при передаче объекта типа TStringGrid в функцию...

Надо сравнить значение одного поля всех объектов между собой и выбрать самое большое значение. C++ ООП
Надо сравнить значение одного поля всех объектов между собой и выбрать самое большое значение. C++ ООП

Передача в функцию динамический массив объектов первого и второго типа
каким способом это можно сделать ? )

9
 Аватар для avgoor
1550 / 877 / 179
Регистрация: 05.12.2015
Сообщений: 2,555
01.02.2017, 21:05
Цитата Сообщение от Notoriously Посмотреть сообщение
Почему это не происходит именно с удалением текущего значения str2,выделения новой памяти и копирования туда строки из str1? (Ну,не только строки, чего бы там вообще не было). Больше всего убивает именно этот "переброс" указателя.
Потому, что вы не определили operator=() с требуемым вам поведением. Есть правило трех: "Если вам нужно определить хоть что-то из: деструктор, конструктор копирования, оператор присваивания - вам нужно определить все 3" (Есть еще правило пяти туда добавляются перемещающий конструктор и перемещающий оператор присваивания). Дефолтный operator=() годится только для классов, которые не управляют памятью (POD).

Цитата Сообщение от Notoriously Посмотреть сообщение
Какое право эта функция имеет трогать адрес ,который принадлежит объекту,переданному туда по значению?
Вы правда полагаете, что если в каком-то классе есть какое-то значения указателя, то сразу же все что лежит по этому указателю будет принадлежать классу? Может быть 100500 одинаковых указателей. Какой из них "владеет" памятью? Проблема на этот раз в не определенном конструкторе копирования т.е. то же самое нарушение правила трех.
1
70 / 70 / 35
Регистрация: 06.07.2016
Сообщений: 415
01.02.2017, 21:12  [ТС]
Цитата Сообщение от avgoor Посмотреть сообщение
Есть правило трех:
Я к сожалению еще не знаком с этими понятиями. Шилдт просто показывает, что происходит при присваивании между объектами и передаче их в функцию,он еще не ввёл понятие копирующего конструктора , а также "перемещающего" конструктора и оператора и ничего толком не объяснил,просто сказал, "Вот так вот".
0
 Аватар для avgoor
1550 / 877 / 179
Регистрация: 05.12.2015
Сообщений: 2,555
01.02.2017, 21:22
Цитата Сообщение от Notoriously Посмотреть сообщение
Я к сожалению еще не знаком с этими понятиями.
Ну, так загуглите и ознакомьтесь. Все вопросы должны уйти.

Но, у меня создалось впечатление, что вы не понимаете, что такое указатели и ссылки. Прочитайте этот пост.
0
70 / 70 / 35
Регистрация: 06.07.2016
Сообщений: 415
01.02.2017, 21:23  [ТС]
Цитата Сообщение от avgoor Посмотреть сообщение
Но, у меня создалось впечатление
Да нет,с этим всё в порядке. Наигрался уже с указателями и адресами вдоволь. Но я привык,что всё чётко и структурировано и уж если где-то с указателями проблема - напутал я в коде, а не просто как-то странно реализован сам механизм языка.
Оно понятно,что на одну и ту же область в памяти могут "смотреть" сколь угодно много указателей. Просто когда это происходит таким вот образом,меня это обескураживает.
0
 Аватар для avgoor
1550 / 877 / 179
Регистрация: 05.12.2015
Сообщений: 2,555
01.02.2017, 21:56
Цитата Сообщение от Notoriously Посмотреть сообщение
а не просто как-то странно реализован сам механизм языка
А как, по вашему, было бы не странно? Что именно обескураживает? То что оператор присваивания по умолчанию просто присвоит всем полям класса значения полей другого класса? А как должно быть?
0
70 / 70 / 35
Регистрация: 06.07.2016
Сообщений: 415
01.02.2017, 23:38  [ТС]
Цитата Сообщение от avgoor Посмотреть сообщение
А как должно быть?
Да лучше бы вообще не было этого присваивания, делал бы всё ручками,был бы уверен,что "нигде ничего не потерялось". Пока что не вижу вообще смысла в этих присваиваниях, ведь у нас в программах всюду динамика,а такие присваивания - лишь рассадник ошибок.
Но может и правда пока не хватает теоретической базы.

Добавлено через 1 час 31 минуту
А при передаче в функцию объекта класса "по значению" создается копия, в которую также происходит обычное копирование переменных? Поэтому и освобождается при выходе память, на которую указывал указатель из оригинала?
0
 Аватар для avgoor
1550 / 877 / 179
Регистрация: 05.12.2015
Сообщений: 2,555
02.02.2017, 17:50
Цитата Сообщение от Notoriously Посмотреть сообщение
А при передаче в функцию объекта класса "по значению" создается копия, в которую также происходит обычное копирование переменных?
Именно. А как эта копия создается - определяется конструктором копирования. Т.е. проблема не в механизмах языка, а в криво реализованном классе.
1
70 / 70 / 35
Регистрация: 06.07.2016
Сообщений: 415
03.02.2017, 00:30  [ТС]
И в этой же теме спрошу, this ускоряет работу программы?
Есть ли разница между
C++
1
Myclass(int _number1, int _number2) { number1 = _number1 ; number2 = _number2;}
и
C++
1
Myclass(int _number1, int _number2) { this -> number1 = _number1 ; this -> number2 = _number2;}
Или это снова же, "псевдооптимизация" ?
0
Форумчанин
Эксперт CЭксперт С++
 Аватар для MrGluck
8216 / 5047 / 1437
Регистрация: 29.11.2010
Сообщений: 13,453
03.02.2017, 18:33
Notoriously, это и не псевдо, это вообще не оптимизация.
Просто явное написание того, что итак делает компилятор.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
03.02.2017, 18:33
Помогаю со студенческими работами здесь

Передача объекта из одного экземпляра класса в другой с запретом обращаться к методам и свойствам этого объекта
Всем привет! Есть класс, в котором используется объект (MyObject, объявленный в private). При создании второго экземпляра этого класса...

Функционирование классов и объектов между собой
Доброго времени суток. Изучая учебник Дейтелов &quot;C++. How to Program&quot;, наткнулся на весьма несложное упражнение для закрепления...

SFML, взаимодействие объектов игры между собой
Помогите , пожалуйста , разобраться.:sorry: Не знаю, как сделать так , чтоб квадрат врезался в стенки? Вот пока то, что есть: #include...

Передача объекта по ссылке или о значению
Да, да, снова этот вопрос. Допустим у меня есть объект Student с полями String surname и String name. Этот объект лежит двух разных листах....

Передача объектов дочерних классов через массив объектов родительского класса в функцию
Здравствуйте. Возможно, вопрос больше относится к теории ООП, но все же я не решился задавать его в теме теории ООП, так как он кажется мне...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
Новые блоги и статьи
Установка Qt-версии Lazarus IDE в Debian Trixie Xfce
volvo 10.02.2026
В общем, достали меня глюки IDE Лазаруса, собранной с использованием набора виджетов Gtk2 (конкретно: если набирать текст в редакторе и вызвать подсказку через Ctrl+Space, то после закрытия окошка. . .
SDL3 для Web (WebAssembly): Работа со звуком через SDL3_mixer
8Observer8 08.02.2026
Содержание блога Пошагово создадим проект для загрузки звукового файла и воспроизведения звука с помощью библиотеки SDL3_mixer. Звук будет воспроизводиться по клику мышки по холсту на Desktop и по. . .
SDL3 для Web (WebAssembly): Основы отладки веб-приложений на SDL3 по USB и Wi-Fi, запущенных в браузере мобильных устройств
8Observer8 07.02.2026
Содержание блога Браузер Chrome имеет средства для отладки мобильных веб-приложений по USB. В этой пошаговой инструкции ограничимся работой с консолью. Вывод в консоль - это часть процесса. . .
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru