Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
maxm
63 / 35 / 25
Регистрация: 17.07.2014
Сообщений: 457
1

Не вызывается конструктор копии

19.09.2015, 13:39. Просмотров 236. Ответов 12
Метки нет (Все метки)

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
#define st system("pause");
#include <iostream>
#include <string.h>
using namespace std;
class temp{
public:
    int a;
    char*p;
    void get(){
        cout << a << " " <<  p << endl;
    }
    temp(){ p = 0; } 
    temp(char*q, int z=1) {
        a = z;
        int len = strlen(q);
        p = new char[len + 2];
        strcpy(p, q);
        strcat(p, "\0");
    }
    ~temp(){ if (*p) delete[]p; }
    temp (const temp &obj){
        int len = strlen(obj.p);
        if (*p) delete[]p;
        p = new char[len + 2];
        strcpy(p, obj.p);
        strcat(p, "\0");
        cout << "aaa" << endl;
    }
    
};
Соурс:

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
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include "h.h"
 
#define st system("pause");
 
using namespace std;
 
 
int main(){
 
    temp* q = new temp("hello mishka", 3);
    temp *q2 = new temp("hello SLAVIK");
    
    q->get();
    q2->get();
    *q2 = *q;
    
    q->get();
    q2->get();
    delete q;
    q2->get();  
    
    st
    return 0;
}

Все ровно выводит мусор. При перегрузке оператора = все работало корректно. Конструктор копии даже не вызывается, если втыкнуть какой нибудь вывод "сработал конст.коп.", то ничего не выводит. Почему он не вызывается???
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
19.09.2015, 13:39
Ответы с готовыми решениями:

Почему не вызывается конструктор копии?
Почему не вызывается конструктор копии? class CPoint { friend...

При создании класса конструктор вызывается 2 раза, затем вызывается деструктор о_О
Вот такой кодclass A { public: A(){} virtual ~A(){} }; class C {...

this(Всегда ли вызывается конструктор при не явной передачи объекта в конструктор)
class Test { int i; public: void test(int i) { this -&gt; i = i;...

Не вызывается конструктор
Есть конструктор, который я вызываю если, число, которое я передаю больше 20....

конструктор копии
Мне кажется что здесь также должен вызывать конструктор копия при возврате...

12
zss
Модератор
Эксперт С++
7178 / 6677 / 4226
Регистрация: 18.12.2011
Сообщений: 17,622
Завершенные тесты: 1
19.09.2015, 13:51 2
Нарушено Правило ТРЕХ
0
maxm
63 / 35 / 25
Регистрация: 17.07.2014
Сообщений: 457
19.09.2015, 13:55  [ТС] 3
Но раньше делал без перегркзки, работало нормально.
Или наоборот, перегрузка без конст. копии.\

Более того, если написать и перегрузку, и конст. копии, вылетает прога.
0
rikimaru2013
19.09.2015, 14:06
  #4

Не по теме:

С 20 по 27 строку "код" ваш если отдалится можно увидеть пингвинчика. Классно рисуете, вот бы еще нормально код писать)

0
cyb0rg_01
Фрилансер
547 / 340 / 96
Регистрация: 05.05.2014
Сообщений: 2,396
19.09.2015, 14:18 5
C++
1
*q2 = *q;
Перегрузка оператора = отсутствует в этом вся причина. Попробуйте передать объект по значению в какую-нибудь ф-цию и все заработает:
C++
1
2
3
void SomeFunction(temp ob)
{
}
0
maxm
63 / 35 / 25
Регистрация: 17.07.2014
Сообщений: 457
19.09.2015, 15:39  [ТС] 6
C++
1
2
3
4
5
6
7
8
9
temp operator=(temp obj){
        int len = strlen(obj.p);
        if (*p) delete[]p;
        p = new char[len + 2];
        strcpy(p, obj.p);
        strcat(p, "\0");
        a = obj.a;
        return *this;
    }
Мейн:

C++
1
2
3
4
5
6
7
8
    temp* q = new temp("hello mishka", 3);
    temp *q2 = new temp("hello SLAVIK");
    
    q->get();
    q2->get();
    *q2 = *q;   
    delete q;
    q2->get();
Это работало нормально. После манипуляций с конструктором я вернул все на место, т.к. это работало, но теперь эта прога вылетает во время удаления объекта q

То есть перегрузка работает нормально, но теперь не удаляется объект. Почему??? Вылетает окошко во время выполнения, где пишет Expression:_BLOCK_TYPE_IS_VALID(pHead->nBlockUse)
0
zss
Модератор
Эксперт С++
7178 / 6677 / 4226
Регистрация: 18.12.2011
Сообщений: 17,622
Завершенные тесты: 1
19.09.2015, 15:53 7
1.
Цитата Сообщение от maxm Посмотреть сообщение
temp operator=(temp obj){
C++
1
temp& operator=(temp obj){
2.
Цитата Сообщение от maxm Посмотреть сообщение
strcat(p, "\0");
Там ноль уже поставлен функцией strcpy. Это лишнее.
0
maxm
63 / 35 / 25
Регистрация: 17.07.2014
Сообщений: 457
19.09.2015, 15:56  [ТС] 8
1
temp& operator=(temp obj){

аналогично вылетает
и вообще говоря, мой вариант работает, перегрузка срабатывает, т.к я выводил в ней "сработала перегрузка" и это появлялось. Проблема уже в удалении. Не хочет удалять, вылетает
0
DrOffset
8130 / 4713 / 1152
Регистрация: 30.01.2014
Сообщений: 7,683
19.09.2015, 16:03 9
Цитата Сообщение от zss Посмотреть сообщение
temp& operator=(temp obj){
C++
1
temp& operator=(temp const & obj)
Цитата Сообщение от maxm Посмотреть сообщение
Но раньше делал без перегркзки, работало нормально.
Забудь про это. Прошлый опыт ничто, нужно ориентироваться на объективную корректность программы, а не на "раньше работало".

Цитата Сообщение от maxm Посмотреть сообщение
и вообще говоря, мой вариант работает,
Да не работает он. Даже если не падает.
У тебя там миллион ошибок.
Взять хотя бы 23 строку в коде из первого поста.
В конструкторе копирования она вообще не нужна.
2
maxm
63 / 35 / 25
Регистрация: 17.07.2014
Сообщений: 457
19.09.2015, 16:14  [ТС] 10
temp& operator=(temp const & obj)
вот это заработало, спасибо

а когда нужно добавлять амперсант?
если оба указателя на классы, то и temp& , и & obj ??
0
DrOffset
8130 / 4713 / 1152
Регистрация: 30.01.2014
Сообщений: 7,683
19.09.2015, 16:18 11
maxm, вот, лови - разбирайся.
Кликните здесь для просмотра всего текста

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
class temp
{
public:
    int    a;
    char * p;
    void get()
    {
        cout << a << " " <<  p << endl;
    }
    temp() 
        : a(0), p(0) 
    { } 
    temp(char const * q, int z = 1) 
        : a(z)
    {
        size_t len = strlen(q);
        p = new char[len + 1];
        strcpy(p, q);
    }
    ~temp()
    { 
        delete[] p; 
    }
    temp(const temp &obj)
        : a(obj.a), p(0)
    {
        if(obj.p)
        {
            size_t len = strlen(obj.p);
            p = new char[len + 1];
            strcpy(p, obj.p);
        }
    }
    temp & operator=(temp const & obj)
    {
        if(&obj != this)
        {
            a = obj.a;
            if(!obj.p)
            {
                delete[] p;
                p = 0;
            }
            else
            {
                size_t len = strlen(obj.p);
                if(!p || strlen(p) < len)
                {
                    delete[] p;
                    p = new char[len + 1];
                }
                strcpy(p, obj.p);
            }
        }
        return *this;
    }
};

PS. Все изначально заложенные автором особенности этого класса сохранил, кроме откровенно ненужных.

Добавлено через 2 минуты
Цитата Сообщение от maxm Посмотреть сообщение
а когда нужно добавлять амперсант?
Вот в таком виде:
temp& operator=(temp obj)
каждая операция присваивания приводит еще и к операции копирования, с которой у тебя похоже нелады. Вот и падало.
Амперсанд надо добавлять, когда нужно избежать лишнего копирования.
0
maxm
63 / 35 / 25
Регистрация: 17.07.2014
Сообщений: 457
19.09.2015, 16:22  [ТС] 12
А как сделать это без перегрузки, а с конструктором копии??

C++
1
2
3
4
5
6
7
8
    temp (const temp &obj){
        int len = strlen(obj.p);
        if (*p) delete[]p;
        p = new char[len + 1];
        strcpy(p, obj.p);
        a = obj.a;
        cout << "CC" << endl;
    }
Вот этот не вызывается, СС не выводится и выводится мусор после удаления:

C++
1
2
3
4
5
6
7
    q->get();
    q2->get();
    *q2 = *q;
    q->get();
    q2->get();
    delete q;
    q2->get();
0
DrOffset
8130 / 4713 / 1152
Регистрация: 30.01.2014
Сообщений: 7,683
19.09.2015, 16:29 13
Цитата Сообщение от maxm Посмотреть сообщение
А как сделать это без перегрузки, а с конструктором копии??
Что именно?
Если речь про вот этот код:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
int main(){
 
    temp* q = new temp("hello mishka", 3);
    temp *q2 = new temp("hello SLAVIK");
    
    q->get();
    q2->get();
    *q2 = *q; // <<- тут
    
    q->get();
    q2->get();
    delete q;
    q2->get();  
    
    return 0;
}
То никак. В этом коде используется оператор присваивания и именно он и должен быть перегружен.
Конструктор копирования используется, например, вот в таком коде:
C++
1
2
3
4
5
6
int main(){
 
    temp* q = new temp("hello mishka", 3);
    temp *q2 = new temp(*q); // <<- тут
//..............
}
А вообще корректно написанный класс должен либо предоставлять все операции (и копирования и присваивания), либо запрещать их явно на этапе компиляции (если они не нужны). Но вот оставлять на авось - точно нельзя.
0
19.09.2015, 16:29
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
19.09.2015, 16:29

конструктор копии
Здравствуйте. Необходимо было написать небольшую программку, связанную с...

Конструктор копии
Конструктор копии вызывается при: 1)явном создании копии 2)при передачи...

Конструктор копии
Здравствуйте! Не могу никак правильно использовать конструктор копии, тоесть...


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

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
Опции темы

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