2 / 2 / 0
Регистрация: 03.05.2014
Сообщений: 72
1

Реализация конструктора копирования для класса

06.07.2016, 13:52. Показов 1735. Ответов 20
Метки нет (Все метки)

P.S плохо с русским

Этот конструктор копирования сломал мне мозг
И вот что я понемаю когда мы делаем так
C++ (Qt)
1
foo objCopy(obj);
то из obj копируется все в objCopy и есль там выделена память то теперь у нас 2 указателя на один участок память и при вызове деструктора он постарается удалить 2 раза один и тотже участок паметь что преведет к ощибке
OK теперь почему вот этот код , мой код не работает

Header.h
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#ifndef STACK_H_
#define STACK_H_
 
#include <iostream>
#pragma warning(disable : 4996)
 
using namespace std;
 
class foo
{
    char *str;
    int len;
    static int number;
public:
    foo(const foo&);
    foo();
    void get();
    ~foo();
};
 
#endif
Source.cpp

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include "Header.h"
 
int foo::number = 0;
foo::foo()
{
    cout << "Simple Constructor\n";
}
foo::foo(const foo &st)
{
    len = strlen(st.str);
    str = new char[len+1];
    strcpy(str,st.str);
    number++;
    cout << str << endl;
}
void foo::get(){cin>>str;}
foo::~foo()
{
    cout << number-- << endl;
    delete [] str;
}
ConsoleApplication2.cpp

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
 #include "Header.h"
 
int main()
{
    foo f1;
    f1.get();
    foo f2 = f1;
 
 
    system("pause");
    return 0;
}
А вот и сама ощибка
Реализация конструктора копирования для класса

Код в картинах
Реализация конструктора копирования для класса

Реализация конструктора копирования для класса

Реализация конструктора копирования для класса


Проясните пожалуиста?
__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
06.07.2016, 13:52
Ответы с готовыми решениями:

Реализация конструктора копирования для двумерного динамического массива
Практически реализовал, не понимаю, почему не получается... #include &lt;iostream&gt; #include...

Определение конструктора копирования для производного класса
Как написать определение конструктора копирования для производного класса, а именно копировании...

Реализация конструктора копирования и перегрузки =
#include &lt;iostream&gt; #include &lt;cstring&gt; using namespace std; class Cow{ private: char...

Переопределение конструктора копирования абстрактного класса, на клонирование дочерних объектов
Здравствуйте. Помогите решить следующую проблему. Есть абстрактный класс Object, у которого есть...

20
1550 / 875 / 179
Регистрация: 05.12.2015
Сообщений: 2,555
06.07.2016, 13:56 2
Цитата Сообщение от vpavlov76 Посмотреть сообщение
Проясните пожалуиста?
А что тут прояснять: Кто в простом конструкторе память выделять будет?
0
Don't worry, be happy
17758 / 10526 / 2030
Регистрация: 27.09.2012
Сообщений: 26,502
Записей в блоге: 1
06.07.2016, 13:57 3
Цитата Сообщение от vpavlov76 Посмотреть сообщение
OK теперь почему вот этот код , мой код не работает
Хотя бы потому, что указатель str у Вас не инициализируется нужным значением,
а в конструкторе копий, соответственно не проверяется.
0
2 / 2 / 0
Регистрация: 03.05.2014
Сообщений: 72
06.07.2016, 14:14  [ТС] 4
avgoor, Croessmah, тогда я вас разочерую
При инизиализации str в обычно конструкторе скажем так
C++ (Qt)
1
2
str = new char;   // что и выделет толька один байт : глупо конечно потомучто char *str должен выделять паметь где 
//будут вбиты символы char *str = "адрес этой строки"
но если иницализировать в обычном кострукторе вот так
C++ (Qt)
1
2
3
str = new char[10]; // то при вызове функции f1.get() и передать там 11 символов и последовательно вызов
//конструктора копирования то компилятор мне скажет что недостаточон память...что как я думаю говорит про то что 
//в еострукторе копирования поля str = new char[len+1]; вообще не работает потомучто str уже выделел память на 10байт
я попробовал сделать так и не сработало
0
1550 / 875 / 179
Регистрация: 05.12.2015
Сообщений: 2,555
06.07.2016, 14:18 5
vpavlov76, Т.е. вы считаете, что не надо выделять память вообще?
0
2 / 2 / 0
Регистрация: 03.05.2014
Сообщений: 72
06.07.2016, 14:19  [ТС] 6
Вот так вот
Миниатюры
Реализация конструктора копирования для класса   Реализация конструктора копирования для класса   Реализация конструктора копирования для класса  

0
Don't worry, be happy
17758 / 10526 / 2030
Регистрация: 27.09.2012
Сообщений: 26,502
Записей в блоге: 1
06.07.2016, 14:21 7
Цитата Сообщение от vpavlov76 Посмотреть сообщение
тогда я вас разочерую
Я Вас тоже.
В конструкторе без параметров:
C++
1
2
3
4
foo::foo():str(nullptr), len(0)
{
    cout << "Simple Constructor\n";
}
К копировальщике:
C++
1
2
3
4
5
6
7
8
9
10
11
foo::foo(const foo &st): str(nullptr), len(0)
{
    if(st.str == nullptr){
        return;
    }
    len = strlen(st.str);
    str = new char[len+1];
    strcpy(str,st.str);
    number++;
    cout << str << endl;
}
0
1550 / 875 / 179
Регистрация: 05.12.2015
Сообщений: 2,555
06.07.2016, 14:27 8
vpavlov76, И что? Если вы не знаете, сколько памяти выделить - это ваши проблемы, а не компилятора. Выходов много - выделить с запасом, читать посимвольно с перевыделением, проанализировать буфер ввода, читать в std::string...
А ваш код пишет по неинициализированному указателю.

Добавлено через 2 минуты
Цитата Сообщение от vpavlov76 Посмотреть сообщение
тогда я вас разочерую
разочарую - проверочное слово - char.
2
2 / 2 / 0
Регистрация: 03.05.2014
Сообщений: 72
06.07.2016, 14:27  [ТС] 9
avgoor, есль вы не знаете сколько память выделать используите STL::List или double List
но я здесь это не использую
0
1550 / 875 / 179
Регистрация: 05.12.2015
Сообщений: 2,555
06.07.2016, 14:29 10
Цитата Сообщение от vpavlov76 Посмотреть сообщение
но я здесь это не использую
Ну, что я могу сказать. Наслаждайтесь дальше окошком "Debug assertion failed".
0
Заблокирован
06.07.2016, 15:02 11
Цитата Сообщение от vpavlov76 Посмотреть сообщение
foo::foo()
{
* * cout << "Simple Constructor\n";
}
- где обнуление str ? После такого конструктора str является битым поинтером в результате чего в деструкторе будет выскакивать ошибка

Добавлено через 2 минуты
Цитата Сообщение от vpavlov76 Посмотреть сообщение
void foo::get(){cin>>str;}
как можно осущетсвлять ввод по битому поинтеру?

Добавлено через 3 минуты
Вот код без перечисленных выше ошибок
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
#include <iostream>
#include <cstring>
using namespace std;
 
class foo
{
    char *str;
    int   len;
    static int number;
public:
    foo();
    foo(const foo&);
    void get();
    ~foo();
};
 
int foo::number = 0;
foo::foo()
{
    str = 0;
    len = 0;
    cout << "Simple Constructor\n";
}
foo::foo(const foo &st)
{
    len = strlen(st.str);
    str = new char[len+1];
    strcpy(str,st.str);
    number++;
    cout << str << endl;
}
void foo::get(){
    static char buf[1024];
    cin.getline(buf, 1024);
    len = strlen(buf);
    str = new char[1 + len];
    strcpy(str, buf);
}
foo::~foo()
{
    cout << number-- << endl;
    delete [] str;
}
 
int main()
{
    foo f1;
    f1.get();
    foo f2 = f1;
 
    return 0;
}
http://ideone.com/MPDEia
stdin copy
test string
stdout copy
Simple Constructor
test string
1
0
0
Don't worry, be happy
17758 / 10526 / 2030
Регистрация: 27.09.2012
Сообщений: 26,502
Записей в блоге: 1
06.07.2016, 15:09 12
Цитата Сообщение от Unknownx Посмотреть сообщение
Вот код без перечисленных выше ошибок
C++
1
2
3
4
5
    len = strlen(st.str);
    str = new char[len+1];
    strcpy(str,st.str);
    number++;
    cout << str << endl;
а ежели в st - пусто?
0
2 / 2 / 0
Регистрация: 03.05.2014
Сообщений: 72
06.07.2016, 15:18  [ТС] 13
Unknownx, первый раз я ощибся сделав
C++ (Qt)
1
cin>>str;
но дело было в том что при создание обиекта памяти небыло выделено и попытка вызывать cin >> str небыло до нажатие Enter..но есль выделять памети то cin >> str ощибкои не являетса
В вашем коде подозрении нет и критиковать не хочу все верно но толька с одной стороны по моему мнению...дело в том что вы уже создаль массив buffer на 1024 байт а это значит что вы задали дипазон
Но сделал я .... во время копиляции str не знает какя длина будет у строки соотвествено и у память которую он должен выделать тоже не знает он узнает после нажатие Enter якобы узнав длину от выделяет память...что делает память динамической какова длина строки такова и длина память.....хотел сказать что нету диапазона выделеной память
Типа такая система и у List STL , List не знает длину ващего списка но вы можете добовлять сколько хотите и удалять тоже
0
Заблокирован
06.07.2016, 15:28 14
vpavlov76, я уже исправил твой код чтобы работало
Цитата Сообщение от vpavlov76 Посмотреть сообщение
В вашем коде подозрении нет и критиковать не хочу все верно но толька с одной стороны по моему мнению...дело в том что вы уже создаль массив buffer на 1024 байт а это значит что вы задали дипазон
- да создал, т.к ты сам сделал консольный ввод, откуда мне знать сколько будешь вводить символов(причём по методологии твой метод ввода должен зваться set а не get но это сильно роли не играет). Контейнеры стл я так понял ты не используешь.

Добавлено через 3 минуты
Цитата Сообщение от Croessmah Посмотреть сообщение
а ежели в st - пусто?
- поставь условие на пустоту, это пожалуй единственный мой недочёт. Как говорят лишь бы придраться.Причём это не я виноват что стрелн не умеет работать с нулевым указателем(могли бы авторы cstring и ввести условие вовнтурь)
0
2 / 2 / 0
Регистрация: 03.05.2014
Сообщений: 72
06.07.2016, 15:29  [ТС] 15
Croessmah, спасибо за помощи но в st пусто не может быть
ХОТЯ ХОЧУ СКАЗТЬ ЧТОБ ДАЛЬШЕ НУ МУЧЕТИ ВСЕХ НАШЕЛ ОТВЕТ НО КОНЕЧНО НЕ ТАК КАК ХОТЕЛОСИ НО ЗАТО СИДЕЛ ДУМАЛ ВСЕТАКИ
и так в ST ну пусто и вот почему

старый код
C++ (Qt)
1
2
3
foo f1;
f1.get(); // cin >> str; вроде строка и попадает в str допустем что пока это так тогда str = "строка"
foo f2(f1); // из f1 в f2 значет и длина уже известа и строка тоже тогда f2.str = f1.str и f2,len = f1.len
изначалина логика была такова но я изменил код не дотрагевая обычный конструктор делая это так
C++ (Qt)
1
2
3
4
5
6
void foo::get(char *s)
{
    len = strlen(s);
    str = new char[len+1];
    strcpy(str,s);
}
ConsoleApplication2.cpp
C++ (Qt)
1
2
3
foo f1;
f1.get("VikelaANDthisislong");
foo f2(f1);
рад что компилятр ничего не сказал
Да решение не из профи но хвалить себя не буду попытаюси сделать более профи
Миниатюры
Реализация конструктора копирования для класса   Реализация конструктора копирования для класса  
0
2 / 2 / 0
Регистрация: 03.05.2014
Сообщений: 72
06.07.2016, 15:40  [ТС] 16
Unknownx, как видеши я изменил код так чтобы мог весть сколько символов хочу и после вызова конструктора копирования жалобы от компилятора нет....но пришлось делать это get-том да еше и не попросить пользователя весть данные а я сам ввел их в арг. функ. что совсем не Логична для настоящии приложение но проблема та решена я могу весть сколька символов захочю и компилятор не скажет что у меня память заполнена
0
Заблокирован
06.07.2016, 15:50 17
vpavlov76, и что ты этим сказать?Сделано конечно же всё дебильно, но я не хочу осокорблять твои чувства кодера поэтому эксперемнтируй дальше. Молодец что пытаешся.
0
2 / 2 / 0
Регистрация: 03.05.2014
Сообщений: 72
06.07.2016, 16:10  [ТС] 18
Unknownx, дебилино или нет не важно пока я учюси такчто ошибки в коде вполне много
НО ПОЯВИЛОСЬ другая проблема дуструктор при вызове f1.get и f2(f1) вроде проблем нет но на самом деле я обнаружел проблему дело в том что оба обиекта указывают на одну и ту же область память и при вызове деструктора логична было бы что компиоятор сообщил про ошибку как я думаю...но он это не делает....а мне надо чтобы при вызове деструктора компилятор сообшил про ощибку потомучто он пытается уничтожеть один и тот же участок память 2 раза
При вызове новой программы адреса меняютса но меня беспокоет то что я не знаю освободил ли дуструктор память занетое ранее что он выдает потом каждый раз новый адрес...
И еше в деструкторе я выожу с помошю cout число статическое почему он не выводет это число на экран отсюда и беспокоиства если cout из деструктора не вызывается значет деуструктор не вызывается вовсе а значет и память не удаляется....
Миниатюры
Реализация конструктора копирования для класса   Реализация конструктора копирования для класса  
0
Заблокирован
06.07.2016, 16:23 19
vpavlov76, выложи в тему полностью проект в архиве а не свои куски куда и скриншоты консоли, я уверен что легко поправлю и покажу где реально сделано плохо и с ошибками а где нет. И чёрт возьми переименуй метод get в set начинает глаз уже от этого несоответвия семантики дёргать.
0
2 / 2 / 0
Регистрация: 03.05.2014
Сообщений: 72
06.07.2016, 16:32  [ТС] 20
Unknownx, какя разница set или get я то знаю что он делает могу назвать и get_char_in_char_for_char
это проста консолька а не реальная прогамма здесь имена функции не так уж и важны
Вложения
Тип файла: zip ConsoleApplication2.zip (657.4 Кб, 5 просмотров)
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
06.07.2016, 16:32
Помогаю со студенческими работами здесь

Реализация конструктора класса
Здравствуйте! Хотел задать такой вопрос: Предположим, имеется класс: class Object { ...

Std::vector добавить новый элемент собственного класса без использования конструктора копирования
Всем привет! Есть один класс, который я хочу хранить в std::vector. Создать массив, с типом...

В чём отличия конструктора копирования и конструктора перемещения? Где и как их нужно использовать?
Помогите разобраться в копирующем и перемещающем конструкторах. В чём их существенное отличие и...

Вызов конструктора для this в констукторе копирования
Мое почтение, уважаемые! Подскажите, пожалуйста, как вызвать конструктор для this в констукторе...


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

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

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2022, CyberForum.ru