Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
mzarb
-211 / 7 / 1
Регистрация: 14.01.2013
Сообщений: 141
#1

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

18.01.2013, 00:05. Просмотров 946. Ответов 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;
}
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
18.01.2013, 00:05     Почему допустимо создавать объект по другому объекту, но нельзя присваивать уже созданный объект, другому созданному объекту?
Посмотрите здесь:

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

как присвоить значения из одного объекта другому объекту - C++
у меня два объекта, мне надо присвоить значения из одного объекта другому объекту, как это можно сделать #include <iostream> using...

Указатель на целочисленный объект. Указать возможные способы доступа к этому объекту. - C++
здарвствуйте все! помогите пожалуйста с заданиями по мере возможностей: 2) Определив указатель на целочисленный объект, укажите возможные...

Классы. Доступ к созданному объекту. - C++
Доброе утро, форум.:friends: Имеется код, чисто для примера. файл book.h #ifndef BOOK_H #define BOOK_H struct Book {

выделить место для объекта с помощью new или создать указатель, объект и присвоить один другому. какая разница? - C++
кроме того что к объекту созданному с помощью new можно будет обращаться только через указатель.

Правильно созданный глобальный объект - C++
Необходимо создать создать несколько объектов классов глобально. Я делаю: Создаю h-файл. в нем объявляю(создаю) объекты. И в срр -...

Как возвратить указатель на объект, созданный в методе? - C++
A* B::ReturnPtrA(){ A a; a.Method1(a.Method2()); //... return &a; } Говорит, что нельзя возвращать указатель...

После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
OhMyGodSoLong
~ Эврика! ~
1243 / 992 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
18.01.2013, 00:08     Почему допустимо создавать объект по другому объекту, но нельзя присваивать уже созданный объект, другому созданному объекту? #2
Потому что как только вы объявляете свой конструктор, стандартная копировалка убирается. Чтобы определить свою, определяйте метод Array& Array::operator=(const Array &other), который и выполнит копирование полей из объекта other в текущий (и вернёт этот же текущий, return *this;).
TrueBit
95 / 95 / 12
Регистрация: 19.11.2012
Сообщений: 195
18.01.2013, 00:14     Почему допустимо создавать объект по другому объекту, но нельзя присваивать уже созданный объект, другому созданному объекту? #3
Цитата Сообщение от ~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();
}
OhMyGodSoLong
~ Эврика! ~
1243 / 992 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
18.01.2013, 01:10     Почему допустимо создавать объект по другому объекту, но нельзя присваивать уже созданный объект, другому созданному объекту? #4
Ага, но только mydata у них общий. Умрёт один объект и отберёт у второго данные. А по-хорошему объект должен снять копию со всего массива. Ну или обеспечить его неудаление, пока на него кто-то ссылается.
Jupiter
Каратель
Эксперт С++
6552 / 3972 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
18.01.2013, 01:13     Почему допустимо создавать объект по другому объекту, но нельзя присваивать уже созданный объект, другому созданному объекту? #5
delete
mzarb
-211 / 7 / 1
Регистрация: 14.01.2013
Сообщений: 141
18.01.2013, 01:53  [ТС]     Почему допустимо создавать объект по другому объекту, но нельзя присваивать уже созданный объект, другому созданному объекту? #6
Всем спасибо! С конструктором копий и выделением под него нового массива, что бы деструктор первого объекта не удалил его, разобрался. Но вот не понял как он себя вызывает бесконечно, если в его объявлении указать не ссылку на объект, а просто объект, то есть не
C++
1
Array(Array &a)
а это
C++
1
Array(Array a)
.
Можете на пальцах объяснить порядок действий или почему так происходит?
Jupiter
Каратель
Эксперт С++
6552 / 3972 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
18.01.2013, 01:59     Почему допустимо создавать объект по другому объекту, но нельзя присваивать уже созданный объект, другому созданному объекту? #7
Цитата Сообщение от mzarb Посмотреть сообщение
а просто объект
если передавать просто объект, то он передается по значению т.е. копируется, вот и получается рекурсия
mzarb
-211 / 7 / 1
Регистрация: 14.01.2013
Сообщений: 141
18.01.2013, 18:33  [ТС]     Почему допустимо создавать объект по другому объекту, но нельзя присваивать уже созданный объект, другому созданному объекту? #8
Jupiter. То есть он будет восприниматься как ещё один конструктор, а не конструктор копирования и он будет выполнятся после первого конструктора, потому что количество конструкторов неограниченно, если у них разные параметры. А как конструктор получит объект на втором проходе(когда сам себя будет вызывать)? Почитав о рекурсии, все ровно не до конца понимаю как это будет выглядеть на примере с объектом.
Если вам не сложно, то могли бы вы привести какой-то схематический пример как это выглядит в памяти, что копируется, куда и зачем или на словах описать поподробней?
Jupiter
Каратель
Эксперт С++
6552 / 3972 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
18.01.2013, 18:51     Почему допустимо создавать объект по другому объекту, но нельзя присваивать уже созданный объект, другому созданному объекту? #9
Цитата Сообщение от mzarb Посмотреть сообщение
То есть он будет восприниматься как ещё один конструктор, а не конструктор копирования
да

Цитата Сообщение от mzarb Посмотреть сообщение
А как конструктор получит объект на втором проходе(когда сам себя будет вызывать)? Почитав о рекурсии, все ровно не до конца понимаю как это будет выглядеть на примере с объектом.
разберитесь в отличии передачи параметров по ссылке, по указателю и по значению
MrGluck
Модератор
Эксперт CЭксперт С++
6997 / 4168 / 594
Регистрация: 29.11.2010
Сообщений: 11,047
18.01.2013, 19:02     Почему допустимо создавать объект по другому объекту, но нельзя присваивать уже созданный объект, другому созданному объекту? #10
Цитата Сообщение от ~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 у них общий. Умрёт один объект и отберёт у второго данные.
и память попытается освободиться дважды, что понесет крах во время выполнения.
mzarb
-211 / 7 / 1
Регистрация: 14.01.2013
Сообщений: 141
19.01.2013, 00:17  [ТС]     Почему допустимо создавать объект по другому объекту, но нельзя присваивать уже созданный объект, другому созданному объекту? #11
Цитата Сообщение от Jupiter Посмотреть сообщение
да


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

P.S. Я может быть задаю глупые вопросы, но в моем понимании не хватает какой-то детали, которую возможно вы все здесь считают очевидной и не нужной для объяснения. По этому и прошу максимально подробно описать что происходит в момент копировании и почему это заставляет повторно вызывать копирование.
Kuzia domovenok
1889 / 1744 / 117
Регистрация: 25.03.2012
Сообщений: 5,922
Записей в блоге: 1
19.01.2013, 01:14     Почему допустимо создавать объект по другому объекту, но нельзя присваивать уже созданный объект, другому созданному объекту? #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;
}
Конструктор вызывается при создании новых объектов, Оператор = при изменении существующих.
mzarb
-211 / 7 / 1
Регистрация: 14.01.2013
Сообщений: 141
19.01.2013, 02:34  [ТС]     Почему допустимо создавать объект по другому объекту, но нельзя присваивать уже созданный объект, другому созданному объекту? #15
Kuzia domovenok, ясно, спасибо за уточнение, но это не дает ответа на мой вопрос. Почему конструктор вызывается бесконечно, если в его параметр передать объект по значению, то есть не по ссылке Array(Array &a), а по значению Array(Array a). Не важно, что это не работает. Меня интересует как это устроено и за счет чего идет бесконечный вызов, а то я встречал только упоминания о нем, а развернутого ответа не нашел, возможно он очевиден, но я его не могу понять. Ещё раз подчеркиваю, мне важно понять как это устроено, а не просто оставить это на поверхностном уровне понимания.
Jupiter
Каратель
Эксперт С++
6552 / 3972 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
19.01.2013, 02:37     Почему допустимо создавать объект по другому объекту, но нельзя присваивать уже созданный объект, другому созданному объекту? #16
Цитата Сообщение от mzarb Посмотреть сообщение
Почему конструктор вызывается бесконечно, если в его параметр передать объект по значению, то есть не по ссылке Array(Array &a), а по значению Array(Array a). Не важно, что это не работает.
все что передается по значению копируется,
копии объектов классов конструируются конструктором копирования,
потому если конструктор копирования принимал бы параметр по значению то и возникла бы бесконечная рекурсия
mzarb
-211 / 7 / 1
Регистрация: 14.01.2013
Сообщений: 141
19.01.2013, 02:46  [ТС]     Почему допустимо создавать объект по другому объекту, но нельзя присваивать уже созданный объект, другому созданному объекту? #17
Jupiter, а как бы тогда выглядела реализация такого такого конструктора копирования?
Jupiter
Каратель
Эксперт С++
6552 / 3972 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
19.01.2013, 02:51     Почему допустимо создавать объект по другому объекту, но нельзя присваивать уже созданный объект, другому созданному объекту? #18
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;
}
mzarb
-211 / 7 / 1
Регистрация: 14.01.2013
Сообщений: 141
19.01.2013, 03:16  [ТС]     Почему допустимо создавать объект по другому объекту, но нельзя присваивать уже созданный объект, другому созданному объекту? #19
Jupiter, спасибо! Хотелось бы уточнить ещё один момент.
Цитата Сообщение от Jupiter Посмотреть сообщение
все что передается по значению копируется,
копии объектов классов конструируются конструктором копирования,
потому если конструктор копирования принимал бы параметр по значению то и возникла бы бесконечная рекурсия
То есть до исполнения тела конструктора копий так и не дойдет?
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
19.01.2013, 04:03     Почему допустимо создавать объект по другому объекту, но нельзя присваивать уже созданный объект, другому созданному объекту?
Еще ссылки по теме:

Как правильно вернуть объект созданный в функции? - C++
Допустим у нас есть функция, которая динамически создает объект и должна его вернуть. К примеру, возьмем динамическое создание массива. ...

В каком месте класса необходимо создавать объект? - C++
Здравствуйте, имеется класс &quot;Player&quot;. Конструктор такой: Player(Level &amp;lvl, int X, int Y); Не знаю в каком месте создать объект класса...

Созданный объект Array<char> удаляется, как только метод convert завершается - C++
Есть простенькая оболочка над массивом Array&lt;T&gt;: template&lt;typename T&gt; class Array { private: T* data; public: const...

Создание полиморфного объекта, зачем создавать указатель на объект базового класса? - C++
Зачем создавать указатель на объект базового класса: Base *A = new Derived Если можно сделать так: Derived *A = new Derived

Почему удаляется объект? - C++
Помогите, пожалуйста, понять почему удаляется объект и как это исправить? Идея следующая: В Source.cpp я создаю два объекта, вызывая...


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

Или воспользуйтесь поиском по форуму:
Jupiter
Каратель
Эксперт С++
6552 / 3972 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
19.01.2013, 04:03     Почему допустимо создавать объект по другому объекту, но нельзя присваивать уже созданный объект, другому созданному объекту? #20
Цитата Сообщение от mzarb Посмотреть сообщение
То есть до исполнения тела конструктора копий так и не дойдет?
в неправильном варианте - не дойдет
Yandex
Объявления
19.01.2013, 04:03     Почему допустимо создавать объект по другому объекту, но нельзя присваивать уже созданный объект, другому созданному объекту?
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru