Форум программистов, компьютерный форум, киберфорум
Наши страницы

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

Войти
Регистрация
Восстановить пароль
 
maxm
62 / 34 / 8
Регистрация: 17.07.2014
Сообщений: 457
#1

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

19.09.2015, 13:39. Просмотров 222. Ответов 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
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Не вызывается конструктор копии (C++):

Почему не вызывается конструктор копии? - C++
Почему не вызывается конструктор копии? class CPoint { friend std::istream &amp;operator&gt;&gt;(std::istream &amp;in, CPoint &amp;obj); friend...

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

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

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

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

Конструктор копии - C++
Здравствуйте! Не могу никак правильно использовать конструктор копии, тоесть создать копию обьекта (массива):( Вот конструктор с...

12
zss
Модератор
Эксперт С++
6634 / 6196 / 2051
Регистрация: 18.12.2011
Сообщений: 16,155
Завершенные тесты: 1
19.09.2015, 13:51 #2
Нарушено Правило ТРЕХ
0
maxm
62 / 34 / 8
Регистрация: 17.07.2014
Сообщений: 457
19.09.2015, 13:55  [ТС] #3
Но раньше делал без перегркзки, работало нормально.
Или наоборот, перегрузка без конст. копии.\

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

Не по теме:

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

0
cyb0rg_01
Фрилансер
437 / 336 / 65
Регистрация: 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
62 / 34 / 8
Регистрация: 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
Модератор
Эксперт С++
6634 / 6196 / 2051
Регистрация: 18.12.2011
Сообщений: 16,155
Завершенные тесты: 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
62 / 34 / 8
Регистрация: 17.07.2014
Сообщений: 457
19.09.2015, 15:56  [ТС] #8
1
temp& operator=(temp obj){

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

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

а когда нужно добавлять амперсант?
если оба указателя на классы, то и temp& , и & obj ??
0
DrOffset
7471 / 4467 / 1015
Регистрация: 30.01.2014
Сообщений: 7,321
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
62 / 34 / 8
Регистрация: 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
7471 / 4467 / 1015
Регистрация: 30.01.2014
Сообщений: 7,321
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
Привет! Вот еще темы с ответами:

конструктор копии - C++
Мне кажется что здесь также должен вызывать конструктор копия при возврате объекта obj из функции Get()! Разве нет? #include &lt;iostream.h&gt;...

Конструктор копии - C++
Конструктор копии вызывается при: 1)явном создании копии 2)при передачи параметров в функцию (по значению) 3)при возвращении объекта...

Вызывается не тот конструктор - C++
При выполнении кода stroka* p=new stroka; p=new stroka(&quot;absd&quot;); Используется конструктор с сигнатурой (const char), а не с...

Конструктор вызывается 2 раза - C++
Помогите пожалуйста найти ошибку. Конструктор вызывается 2 раза. #include &lt;iostream&gt; #include &lt;stdio.h&gt; #include &lt;fstream&gt; using...


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

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

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