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

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

19.09.2015, 13:39. Просмотров 229. Ответов 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;
    }
    
};
Соурс:

http://www.cyberforum.ru/cpp-beginners/thread923669.html
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
Я подобрал для вас темы с готовыми решениями и ответами на вопрос Не вызывается конструктор копии (C++):

При создании класса конструктор вызывается 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
Модератор
Эксперт С++
6952 / 6514 / 4135
Регистрация: 18.12.2011
Сообщений: 17,183
Завершенные тесты: 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
Фрилансер
438 / 338 / 95
Регистрация: 05.05.2014
Сообщений: 2,308
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
Модератор
Эксперт С++
6952 / 6514 / 4135
Регистрация: 18.12.2011
Сообщений: 17,183
Завершенные тесты: 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
7517 / 4513 / 1097
Регистрация: 30.01.2014
Сообщений: 7,362
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
7517 / 4513 / 1097
Регистрация: 30.01.2014
Сообщений: 7,362
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
7517 / 4513 / 1097
Регистрация: 30.01.2014
Сообщений: 7,362
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)при передачи...

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

НЕ вызывается конструктор копирования
НЕ вызывается конструктор копирования (не явно), как сделать чтобы это было...

Наследование(Не вызывается конструктор)
f3=f1+f2; 1) Вызывается Fraction operator+(const Fraction&amp; other) 2) Для...


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

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

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