Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.62/13: Рейтинг темы: голосов - 13, средняя оценка - 4.62
8 / 8 / 2
Регистрация: 14.01.2013
Сообщений: 141

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

18.01.2013, 00:05. Показов 2775. Ответов 22
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Это можно :
C++
1
2
3
Array a(10);
a.set(0,5);
Array b(a);
А это нельзя :
C++
1
2
3
Array a(10);
Array b(20);
a = b;
Объясните пожалуйста в чем дело. Если можно, то поподробней, то есть что именно копируется, с каких мест и когда. Я только знаю, что в первом варианте можно так делать, потому что объект ещё не создан, а тонкостей не знаю(.
Вот полный код :
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
32
33
class Array {
private:
    size_t mysize;
    int *mydata;
public:
    Array(size_t size);
    void set(int i, int val);
    int get(int i);
};
 
Array::Array(size_t size){
    mysize = size;
    mydata = new int [mysize];
}
 
void Array::set(int i, int val){
    mydata[i] = val;
}
 
int Array::get(int i){
    return mydata[i];
}
 
int main() {
    Array a(10);
    a.set(0,7);
    Array b(a); //Первый вариант
    
    Array a(10);
    Array b(20);
    b=a;        //Второй вариант
    return 0;
}
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
18.01.2013, 00:05
Ответы с готовыми решениями:

Как обратиться к созданному объекту, если переменной присвоен уже другой объект?
Всем привет, Допустим, у меня есть класс, назовем его MyClass. Я объявляю переменную x, затем присваиваю ей новый созданный объект на...

Как прикрепить линию к объекту и провести к другому объекту?
Привет. Вот вариант с помощью метода Gizmos.DrawLine. Как видите линия проходит с центра одного объекта в центр другого. Но задумка...

Почему конструктор вызывается при присвоении объекта другому объекту
оператор+ выполняется нормально, но когда уже переменная в sum, на след шаге она вызывает конструктор, ибо у меня в примере 9 выходит. А в...

22
~ Эврика! ~
 Аватар для OhMyGodSoLong
1258 / 1007 / 74
Регистрация: 24.07.2012
Сообщений: 2,002
18.01.2013, 00:08
Потому что как только вы объявляете свой конструктор, стандартная копировалка убирается. Чтобы определить свою, определяйте метод Array& Array::operator=(const Array &other), который и выполнит копирование полей из объекта other в текущий (и вернёт этот же текущий, return *this;).
1
 Аватар для TrueBit
100 / 100 / 47
Регистрация: 19.11.2012
Сообщений: 195
18.01.2013, 00:14
Цитата Сообщение от ~OhMyGodSoLong~ Посмотреть сообщение
Потому что как только вы объявляете свой конструктор, стандартная копировалка убирается. Чтобы определить свою, определяйте метод Array& Array::operator=(const Array &other), который и выполнит копирование полей из объекта other в текущий (и вернёт этот же текущий, return *this;).
А у меня и без стандартного работает, в а установили в б получили:
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
32
33
34
35
36
37
38
#include <iostream>
using namespace std;
class Array {
private:
    size_t mysize;
    int * mydata;
public:
    Array(size_t size);
    void set(int i, int val);
    int get(int i);
};
 
Array::Array(size_t size){
    mysize = size;
    mydata = new int [mysize];
}
 
void Array::set(int i, int val){
    mydata[i] = val;
}
 
int Array::get(int i){
    return mydata[i];
}
 
int main() {
    /*Array a(10);
    a.set(0,7);
    Array b(a); //Первый вариант
    */
    
    Array a(10);
    Array b(20);
    a.set(0,777);
    b=a;        //Второй вариант
    cout << b.get(0);
    cin.get();
}
1
~ Эврика! ~
 Аватар для OhMyGodSoLong
1258 / 1007 / 74
Регистрация: 24.07.2012
Сообщений: 2,002
18.01.2013, 01:10
Ага, но только mydata у них общий. Умрёт один объект и отберёт у второго данные. А по-хорошему объект должен снять копию со всего массива. Ну или обеспечить его неудаление, пока на него кто-то ссылается.
1
Каратель
Эксперт С++
6610 / 4029 / 401
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
18.01.2013, 01:13
delete
0
8 / 8 / 2
Регистрация: 14.01.2013
Сообщений: 141
18.01.2013, 01:53  [ТС]
Всем спасибо! С конструктором копий и выделением под него нового массива, что бы деструктор первого объекта не удалил его, разобрался. Но вот не понял как он себя вызывает бесконечно, если в его объявлении указать не ссылку на объект, а просто объект, то есть не
C++
1
Array(Array &a)
а это
C++
1
Array(Array a)
.
Можете на пальцах объяснить порядок действий или почему так происходит?
0
Каратель
Эксперт С++
6610 / 4029 / 401
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
18.01.2013, 01:59
Цитата Сообщение от mzarb Посмотреть сообщение
а просто объект
если передавать просто объект, то он передается по значению т.е. копируется, вот и получается рекурсия
1
8 / 8 / 2
Регистрация: 14.01.2013
Сообщений: 141
18.01.2013, 18:33  [ТС]
Jupiter. То есть он будет восприниматься как ещё один конструктор, а не конструктор копирования и он будет выполнятся после первого конструктора, потому что количество конструкторов неограниченно, если у них разные параметры. А как конструктор получит объект на втором проходе(когда сам себя будет вызывать)? Почитав о рекурсии, все ровно не до конца понимаю как это будет выглядеть на примере с объектом.
Если вам не сложно, то могли бы вы привести какой-то схематический пример как это выглядит в памяти, что копируется, куда и зачем или на словах описать поподробней?
0
Каратель
Эксперт С++
6610 / 4029 / 401
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
18.01.2013, 18:51
Цитата Сообщение от mzarb Посмотреть сообщение
То есть он будет восприниматься как ещё один конструктор, а не конструктор копирования
да

Цитата Сообщение от mzarb Посмотреть сообщение
А как конструктор получит объект на втором проходе(когда сам себя будет вызывать)? Почитав о рекурсии, все ровно не до конца понимаю как это будет выглядеть на примере с объектом.
разберитесь в отличии передачи параметров по ссылке, по указателю и по значению
0
Форумчанин
Эксперт CЭксперт С++
 Аватар для MrGluck
8216 / 5047 / 1437
Регистрация: 29.11.2010
Сообщений: 13,453
18.01.2013, 19:02
Цитата Сообщение от ~OhMyGodSoLong~ Посмотреть сообщение
Потому что как только вы объявляете свой конструктор, стандартная копировалка убирается.
Убирается лишь конструктор по-умолчанию при явном указании хотя бы одного. Иначе данный код не компилился бы:
C++
1
2
3
4
5
6
7
8
9
10
11
12
class A
{
    public :
        A(){}
};
 
int main()
{
    A a;
    A b = a;
    A c(a);
}
Но определить оператор присваиваний и конструктор копий все же стоит явно т.к.
Цитата Сообщение от ~OhMyGodSoLong~ Посмотреть сообщение
идет работа с памятью и mydata у них общий. Умрёт один объект и отберёт у второго данные.
и память попытается освободиться дважды, что понесет крах во время выполнения.
0
8 / 8 / 2
Регистрация: 14.01.2013
Сообщений: 141
19.01.2013, 00:17  [ТС]
Цитата Сообщение от Jupiter Посмотреть сообщение
да


разберитесь в отличии передачи параметров по ссылке, по указателю и по значению
Переменные, в которых сохраняются параметры, передаваемые функции, также являются локальными для этой функции. Эти переменные создаются при вызове функции и в них копируются значения, передаваемые функции в качестве параметров.
С обычными переменными понятно. А вот что копируется из одного объекта в другой так, что при этом вызывается ещё одно копирование, не понятно. Допустим значение должно копироваться в параметр Array(Array a) , то есть это равносильно тому, если в main будет b=a , а потом получается что при копировании объекта "a" в объект "b", объект b дойдет до этого же конструктора Array(Array a) и снова запустить копирование b=a. Даже если это так, то я не понимаю как это выглядит за ширмой, то есть на этапе компиляции, когда уже нету классов. И как по мне, то далеко не уехать, с таким пониманием данного вопроса, по этому и спрашиваю.
0
 Аватар для Kuzia domovenok
4268 / 3327 / 926
Регистрация: 25.03.2012
Сообщений: 12,532
Записей в блоге: 1
19.01.2013, 00:43
Цитата Сообщение от mzarb Посмотреть сообщение
то есть это равносильно тому, если в main будет b=a , а потом получается что при копировании объекта "a" в объект "b", объект b дойдет до этого же конструктора Array(Array a)
Нет, если в main будет b=a, должен вызваться оператор присвоения
0
8 / 8 / 2
Регистрация: 14.01.2013
Сообщений: 141
19.01.2013, 01:04  [ТС]
Kuzia domovenok, из-за чего тогда происходит бесконечный вызов?

P.S. Я может быть задаю глупые вопросы, но в моем понимании не хватает какой-то детали, которую возможно вы все здесь считают очевидной и не нужной для объяснения. По этому и прошу максимально подробно описать что происходит в момент копировании и почему это заставляет повторно вызывать копирование.
0
 Аватар для Kuzia domovenok
4268 / 3327 / 926
Регистрация: 25.03.2012
Сообщений: 12,532
Записей в блоге: 1
19.01.2013, 01:14
во-первых, есть разница между присвоением и конструированием копии. Похоже, ты до сих пор не уловил это и говоришь не о том, о чём тебе говорят
C++
1
2
3
4
5
6
7
8
9
10
11
void foo(Array parametr){
//...
}
int main(){
Array a(20);
Array b(a);//вызов конструктора копирования
Array c=a;//вызов конструктора копирования
c=b;//вызов оператора присвоения
foo(a);//вызов конструктора копирования
return 0;
}
Конструктор вызывается при создании новых объектов, Оператор = при изменении существующих.
1
8 / 8 / 2
Регистрация: 14.01.2013
Сообщений: 141
19.01.2013, 02:34  [ТС]
Kuzia domovenok, ясно, спасибо за уточнение, но это не дает ответа на мой вопрос. Почему конструктор вызывается бесконечно, если в его параметр передать объект по значению, то есть не по ссылке Array(Array &a), а по значению Array(Array a). Не важно, что это не работает. Меня интересует как это устроено и за счет чего идет бесконечный вызов, а то я встречал только упоминания о нем, а развернутого ответа не нашел, возможно он очевиден, но я его не могу понять. Ещё раз подчеркиваю, мне важно понять как это устроено, а не просто оставить это на поверхностном уровне понимания.
0
Каратель
Эксперт С++
6610 / 4029 / 401
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
19.01.2013, 02:37
Цитата Сообщение от mzarb Посмотреть сообщение
Почему конструктор вызывается бесконечно, если в его параметр передать объект по значению, то есть не по ссылке Array(Array &a), а по значению Array(Array a). Не важно, что это не работает.
все что передается по значению копируется,
копии объектов классов конструируются конструктором копирования,
потому если конструктор копирования принимал бы параметр по значению то и возникла бы бесконечная рекурсия
1
8 / 8 / 2
Регистрация: 14.01.2013
Сообщений: 141
19.01.2013, 02:46  [ТС]
Jupiter, а как бы тогда выглядела реализация такого такого конструктора копирования?
0
Каратель
Эксперт С++
6610 / 4029 / 401
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
19.01.2013, 02:51
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
//copy c-tor
Array::Array(const Array& other)
{
    mysize = other.mysize;
    mydata = new int[mysize];
    
    for (int i = 0; i < mysize; ++i)
        mydata[i] = other.mydata[i];
}
 
//assignment operator
Array& Array::operator = (const Array& other)
{
    if (this != other)
    {
         delete [] mydata;
         mysize = other.mysize;
         mydata = new int[mysize];
    
         for (int i = 0; i < mysize; ++i)
             mydata[i] = other.mydata[i];
    }
    return *this;
}
1
8 / 8 / 2
Регистрация: 14.01.2013
Сообщений: 141
19.01.2013, 03:16  [ТС]
Jupiter, спасибо! Хотелось бы уточнить ещё один момент.
Цитата Сообщение от Jupiter Посмотреть сообщение
все что передается по значению копируется,
копии объектов классов конструируются конструктором копирования,
потому если конструктор копирования принимал бы параметр по значению то и возникла бы бесконечная рекурсия
То есть до исполнения тела конструктора копий так и не дойдет?
0
Каратель
Эксперт С++
6610 / 4029 / 401
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
19.01.2013, 04:03
Цитата Сообщение от mzarb Посмотреть сообщение
То есть до исполнения тела конструктора копий так и не дойдет?
в неправильном варианте - не дойдет
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
19.01.2013, 04:03
Помогаю со студенческими работами здесь

Движение 1 объекта к другому объекту
Как делать так, чтобы объект 1 считывал координаты объекта 2 и двигался к нему?

Привязать элемент к другому объекту
В groupBox1 «Найденные файлы» может перечисляться до 6 файлов. И когда программа их находит groupBox изменяет высоту и закрывает второй...

Движение объекта к другому объекту
На углу экрана(без разница где) стоит маленькое изображение коробки, а на других местах другие изображения разных предметов. Когда нажимаю...

Передача объектов в качестве параметров другому объекту
Добрый день, подскажите как правильно передать объекты в качестве параметров другому объекту чтобы при этом еще и соблюсти инкапсуляцию ...

Как сделать перемещение объекта к другому объекту
Я еще новичок, но... Надо чтобы при нажатии на объект1 он находил бы на сцене объект2 и перемещался к нему. Проблема в отслеживании...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru