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

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

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 10, средняя оценка - 4.70
OMGHero
2 / 2 / 0
Регистрация: 16.02.2011
Сообщений: 36
#1

Почему создаются новые объекты? - C++

19.02.2011, 01:03. Просмотров 1239. Ответов 21
Метки нет (Все метки)

Всем доброго времени суток!
Я не могу понять где создаются новые объекты
Есть у меня простенький класс
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
class data 
{
    char* str;
public:
    data(): str("Hi")
    {}
    data(char* ch): str(ch)
    {}
    void setData(char* ch)
    {
        str = ch;
    }
    void printData()
    {
        cout << str << endl;
    }
    virtual ~data ()
    {
        cout << "data deleted\n";
    }
    data& operator= (data& v)
    {
        str = v.str;
        return *this;
    }
};
Обратите внимение на перегруженный оператор = . Если я возвращаю ссылку на data (как в коде), то при присваивании одго экземпляра класса другому, деструктор ничего не пише мне в консоль. Если я возвращаю просто data
C++
1
2
3
4
5
    data operator= (data& v)
    {
        str = v.str;
        return *this;
    }
то при присваивании в консоле дает о себе знать деструктор.
Зачем компилятор создет еще один экземпляр класса data что бы просто передать *this ?
Если кто понимает, то объясните пожалуйста.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
19.02.2011, 01:03     Почему создаются новые объекты?
Посмотрите здесь:

Создаются одинаковые объекты - C++
Доброго времени суток. Начал изучать ООП и столкнулся с проблемой. Пишу класс работы с матрицами. Имеется такой конструктор: ...

Классы: Не создаются объекты класса Apple - C++
Includes.h #include &lt;stdlib.h&gt; #include &lt;gl\glut.h&gt; #include &lt;math.h&gt; #include&lt;stdio.h&gt; #include&lt;time.h&gt; #include&lt;stdio.h&gt; ...

Объекты каких потоков автоматически создаются при запуске программы - C++
Здраствуйте, могу конечно немного переврать вопрос, но звучит примерно так: Объекты каких потоков автоматически создаются при запуске...

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

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

Почему при программировании C++/Win32 создаются элементы старого вида? - C++
И снова всем здравствуйте!!! Я продолжаю грызть гранит программирования на C++ В общем проблема следующая при создании приложения Win32 в...

Список указателей на авторские объекты, я могу воспользоваться только первым его элементом. Почему? - C++
Друзья! Короче создал ПРОСТОЙ класс всего с одним полем и функцией которая выводит значение этого поля. Создал массив из 2-х указателей на...

После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
silent_1991
Эксперт С++
4960 / 3036 / 149
Регистрация: 11.11.2009
Сообщений: 7,027
Завершенные тесты: 1
19.02.2011, 01:07     Почему создаются новые объекты? #2
Потому что вы возвращаете не ссылку, а объект типа data. Чтобы вернуть объект, надо его скопировать в точку вызова, а потом удалить (тот, что был в функции). И компилятору пофиг, что это *this и что после выхода из функции он не уничтожится - вы ему сказали возвращать объект - он это и делает.
OMGHero
2 / 2 / 0
Регистрация: 16.02.2011
Сообщений: 36
19.02.2011, 09:50  [ТС]     Почему создаются новые объекты? #3
Я не понял.
Какой удаляется объект?

Кстатиб такой код тоже вызывет деструктор 1 раз (при присваивании)
C++
1
2
3
4
5
    data operator= (data& v)
    {
        str = v.str;
        return data(str);
    }
silent_1991
Эксперт С++
4960 / 3036 / 149
Регистрация: 11.11.2009
Сообщений: 7,027
Завершенные тесты: 1
19.02.2011, 10:16     Почему создаются новые объекты? #4
OMGHero, вы для того, чтобы вернуть объект, создаёте временный, а именно data (str). При возврате объекта вызывается конструктор копии, который копирует этот временный объект в точку вызова, чтобы он стал результатом операции присваивания. Но в функции ведь осталась изначальная копия этого объекта, и при выходе из функции все локальные переменные должны быть уничтожены, следовательно, будет вызван деструктор для этого временного объекта, который был создан в функции как data (str).
OMGHero
2 / 2 / 0
Регистрация: 16.02.2011
Сообщений: 36
19.02.2011, 10:32  [ТС]     Почему создаются новые объекты? #5
OMGHero, вы для того, чтобы вернуть объект, создаёте временный, а именно data (str). При возврате объекта вызывается конструктор копии, который копирует этот временный объект в точку вызова, чтобы он стал результатом операции присваивания. Но в функции ведь осталась изначальная копия этого объекта, и при выходе из функции все локальные переменные должны быть уничтожены, следовательно, будет вызван деструктор для этого временного объекта, который был создан в функции как data (str).
Да, этот механизм я понял. Функция создает один объект data (str), потом его уничтожает.
Не понятно что тут создается:
C++
1
2
3
4
5
6
 
 data operator= (data& v)
{
        str = v.str;
        return *this;
}
This не уничтожается. В обоих случаях при выполнении присваивания деконструктор вызывается только один раз. В превом случае понятно что саздается/удаляется (data(str)), во втором нет.
lemegeton
2923 / 1352 / 135
Регистрация: 29.11.2010
Сообщений: 2,725
19.02.2011, 10:35     Почему создаются новые объекты? #6
Цитата Сообщение от OMGHero Посмотреть сообщение
Какой удаляется объект?
Временный. Который программа создаст для того, чтобы передать копию *this в
C++
1
2
3
4
5
* * * * data operator= (data& v)
* * * * {
* * * * * * * * str = v.str;
* * * * * * * * return data(str);
* * * * }
Вы же не ссылку возвращаете, и не указатель, а копию данных. Вот и создается копия класса data, которая удаляется после возвращения значения.

Кстати, некорректно работаете со строками. Вот пример, в котором никто никуда лишний раз не удаляется и содержимое класса Data передается по ссылке:
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
#include <cstdio>
#include <cstring>
 
class Data {
 public:
  Data() : string_(NULL) {}
  explicit Data(const char *string) : string_(NULL) {
    SetData(string);
  }
  ~Data() {
    printf("Debug: Calling destructor %d, '%s'.\n", (int)this, string_);
    delete string_;
  }
  void SetData(const char *string) {
    delete string_;
    string_ = strcpy(new char[strlen(string) + 1], string);
  }
  char *GetData() const { return string_; }
  Data &operator=(const Data &other) {
    if (this != &other)
      SetData(other.GetData());
    return *this;
  }
 private:
  char *string_;
};
 
int main(int argc, char *argv[]) {
  Data a("world!"), b("Hello"), c;
  c = a;
  a = b;
  b = c; // Меняем местами a и b;
  printf("%s %s\n", a.GetData(), b.GetData());
  return 0;
}
Цитата Сообщение от OMGHero Посмотреть сообщение
Не понятно что тут создается:
C++
1
2
3
4
5
data operator= (data& v)
{
        str = v.str;
        return *this; // возвращаем по значению, то бишь копию *this
}
Как что? Копия *this, конечно.
OMGHero
2 / 2 / 0
Регистрация: 16.02.2011
Сообщений: 36
19.02.2011, 11:00  [ТС]     Почему создаются новые объекты? #7
lemegeton, а почему так копируете строки
C++
1
2
3
4
5
  
void SetData(const char *string) {
    delete string_;
    string_ = strcpy(new char[strlen(string) + 1], string);
 }
почему просто указатель не присвоить?

Вы же не ссылку возвращаете, и не указатель, а копию данных. Вот и создается копия класса data, которая удаляется после возвращения значения.
Тогда получается что в этом случае деструктор должен вызываться 2 раза
C++
1
2
3
4
5
        data operator= (data& v)
        {
                str = v.str;
                return data(str);
        }
один раз чтобы возвратить объект (возвращаем же копию данных). А второй раз - удалить data (str)
silent_1991
Эксперт С++
4960 / 3036 / 149
Регистрация: 11.11.2009
Сообщений: 7,027
Завершенные тесты: 1
19.02.2011, 13:24     Почему создаются новые объекты? #8
В случае
C++
1
2
3
4
5
data operator= (data& v)
{
        str = v.str;
        return *this;
}
будет создан временный объект, копия *this, который будет возвращён и удалён. В случае
C++
1
2
3
4
5
data operator= (data& v)
{
        str = v.str;
        return data (str);
}
вы вручную создаёте временный объект (data (str) - объект без имени), который будет скопирован в точку вызова, а потом удалён.

Добавлено через 3 минуты
Очень хочется получить сообщение 4 раза - пишите так:
C++
1
2
3
4
5
6
data operator= (data& v)
{
    str = v.str;
    data temporary_object(str);
    return temporary_object;
}
Здесь будет вызван деструктор для удаления temporary_object при выходе из функции (ещё до возвращения копии в точку вызова), а потом, после возврата копии будет ещё и вызван деструктор для удаления автоматически созданного временного объекта.
OMGHero
2 / 2 / 0
Регистрация: 16.02.2011
Сообщений: 36
19.02.2011, 13:32  [ТС]     Почему создаются новые объекты? #9
Понял )

Добавлено через 7 минут
Цитата Сообщение от silent_1991 Посмотреть сообщение
Очень хочется получить сообщение 4 раза - пишите так:

data operator= (data& v)
{
str = v.str;
data temporary_object(str);
return temporary_object;
}
Здесь будет вызван деструктор для удаления temporary_object при выходе из функции (ещё до возвращения копии в точку вызова), а потом, после возврата копии будет ещё и вызван деструктор для удаления автоматически созданного временного объекта.
Этот код вызывает один раз деструктор. Проверьте.
lemegeton
2923 / 1352 / 135
Регистрация: 29.11.2010
Сообщений: 2,725
19.02.2011, 13:54     Почему создаются новые объекты? #10
Цитата Сообщение от OMGHero Посмотреть сообщение
почему просто указатель не присвоить?
Ну, во-первых, такое присваивание строк deprecated, во-вторых, чтобы иметь копию значения, а не ссылку на него.
C++
1
2
3
4
5
6
  // предположим, есть char  *string, содержащий "123\0";
  char *a = string;
  // варианты выстрелить себе в ногу:
  srting[0] = '\0'; // изменив строку
  delete [] string; // или даже освободив память
  printf("%s\n", a); // ?????????
silent_1991
Эксперт С++
4960 / 3036 / 149
Регистрация: 11.11.2009
Сообщений: 7,027
Завершенные тесты: 1
19.02.2011, 14:01     Почему создаются новые объекты? #11
OMGHero, проверил. Вывод
Код
data deleted
data deleted
data deleted
data deleted
Добавлено через 5 минут
Вообще говоря полезно пробежаться по коду трассировщиком и воочию убедиться, что и где вызывается. Мне очень нравится трассировщик у MSVS2010, им и пользуюсь. Только что специально ради вас прогнал код - вызовы деструкторов:
при выходе из функции operator=, до возврата значения,
после возврата значения
при выходе из main (для удаления d1),
при выходе из main (для удаления d2)
В main у меня были созданы только два объекта, чтобы проверить присваивание.
OMGHero
2 / 2 / 0
Регистрация: 16.02.2011
Сообщений: 36
19.02.2011, 14:07  [ТС]     Почему создаются новые объекты? #12
странно, у меня только один раз (без учета удаления объектов d1 и d2)
щас буду разбираться
silent_1991
Эксперт С++
4960 / 3036 / 149
Регистрация: 11.11.2009
Сообщений: 7,027
Завершенные тесты: 1
19.02.2011, 14:19     Почему создаются новые объекты? #13
Если интересно, вот код (вдруг вы чего у себя не поменяли или ещё что):
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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#include <iostream>
 
using namespace std;
 
class data 
{
    char* str;
public:
    data(): str("Hi")
    {
    }
 
    data(char* ch): str(ch)
    {
    }
    
    data(const data &original):
    str(original.str)
    {
    }
 
    void setData(char* ch)
    {
        str = ch;
    }
    
    void printData()
    {
        cout << str << endl;
    }
    
    virtual ~data ()
    {
        cout << "data deleted\n";
    }
    
    data operator=(data& v)
    {
        str = v.str;
 
        data temporary_object(str);
 
        return temporary_object;
    }
};
 
int main()
{
    data d1("Hello");
    data d2("World");
 
    d1.printData();
    d2.printData();
 
    d1 = d2;
 
    d1.printData();
    d2.printData();
 
    return 0;
}
Вот вывод:
Код
Hello
World
data deleted
data deleted
World
World
data deleted
data deleted
Добавлено через 1 минуту
Ещё для наглядности добавил конструктор копии, чтобы при трассировке видеть, когда он вызывается, на работу деструкторов он, естественно, не влияет.
fasked
Эксперт С++
4933 / 2513 / 180
Регистрация: 07.10.2009
Сообщений: 4,311
Записей в блоге: 1
19.02.2011, 14:26     Почему создаются новые объекты? #14
silent_1991, а я обычно смотрю примерно вот так
код и результат
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
#include <iostream>
 
class sample {
public:
    sample() {
        std::cout << "create of sample object: "    // comment
              << this << std::endl;         // object
    }
 
    sample(const sample& s) {
        std::cout << "create of sample object: "
              << this << std::endl;         // object
    }
 
    sample& operator = (const sample& s) {
        return *this;
    }
 
    ~sample() {
        std::cout << "destroy of sample object: "   // comment
              << this << std::endl;         // object
                  
    }
};
 
int main()
{
    sample a, c;
    sample b = a;
    
    c = b;
 
    return 0;
}
Код
create of sample object: 001BFE8F
create of sample object: 001BFE83
create of sample object: 001BFE77
destroy of sample object: 001BFE77
destroy of sample object: 001BFE83
destroy of sample object: 001BFE8F
. Видно какой объект создался и какой удалился.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
19.02.2011, 14:32     Почему создаются новые объекты?
Еще ссылки по теме:

Контролы создаются, но пропадают - C++
создаю контролы циклом void CSomeDlg::OnOK() { CButton m_cV; for (int i = 1; i&lt;18; i++) { m_cV.Create(ну тут...

OpenMP, не создаются потоки - C++
Привет всем. Подскажите пожалуйста по такой штуке: делаю задачу &quot;Производители-потребители&quot;, начал проверять что хотя б создаётся...

как создаются 3д игры на с++? - C++
как создаются 3д игры на с++?

Как на си++ создаются приложения с GUI? - C++
Расскажите, а? Например в Visual basic'е просто и понятно, с первого захода в среду можно что-нибудь простенькое с граф. интерфейсом...

Как создаются динамические структуры - C++
Добрый вечер всем!!!:) Подскажите пожалуйста, как создаются динамические структуры. Если не сложно, объясните, как из этой вот структуры...


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

Или воспользуйтесь поиском по форуму:
silent_1991
Эксперт С++
4960 / 3036 / 149
Регистрация: 11.11.2009
Сообщений: 7,027
Завершенные тесты: 1
19.02.2011, 14:32     Почему создаются новые объекты? #15
fasked, не, старый добрый метод принтэфной отладки, конечно, никто не отменял))) Но мне как-то в последнее время удобно пользоваться трассировщиком, тем более что мелкомягкие в этот раз действительно на славу постарались)))
Yandex
Объявления
19.02.2011, 14:32     Почему создаются новые объекты?
Ответ Создать тему
Опции темы

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