227 / 75 / 31
Регистрация: 17.07.2015
Сообщений: 774
1

Реализовать пользовательский класс "Smartpointer"

13.12.2015, 10:58. Показов 1139. Ответов 8
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Выходит мне нужно убирать один из деструкторов? Как правильно оформить что бы работали оба деструктора?
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
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<cstring>
using namespace std;
template<typename T>
class smartpointer
{
public:
    smartpointer(T*ob) :sp(ob) { cout << "\npointer created\n"; }
    ~smartpointer() { delete sp; cout << "\npointer deleted\n"; }
    T*operator->() { return sp; }
    T&operator*() { return *sp; }
private:
    T*sp;
 
};
//template<typename t>
class tralala
{
public:
    tralala():aka(nullptr) { cout << "\nempty object created\n"; }  
    tralala(char*g) :aka(new char[strlen(g) + 1]) { strcpy(aka, g); cout << "\ninittialized object created\n"; }
    void Print() { cout << aka << endl; }
    ~tralala() { delete[] aka; cout << "\naka deleted\n"; }
private:
    char*aka;
};
int main()
{
    tralala one("trololo");
    one.Print();
    {
        smartpointer<tralala>pn(new tralala(one));
        pn->Print();
    }
    
    cout << "**************\n";
    //one.Print();
 
 
    return 0;
}
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
13.12.2015, 10:58
Ответы с готовыми решениями:

Реализовать пользовательский класс комплексных чисел
Помогите пожалуйста сделать задание - программу вычисления комплексного числа. Есть рабочая,...

Реализовать пользовательский класс "Двунаправленный список"; реализовать добавление и удаление элементов
Записи в линейном списке содержат ключевое поле типа *char(строка символов). Сформировать...

Реализовать произвольный пользовательский класс с функциями-членами Put и Show
Создать несколько обьектов. Написать функции: 1) для ввода данных по обьекту(как Put) 2) для...

Пользовательский класс String: реализовать копирование строки и вывод её на консоль (найти ошибки в коде)
Привет. Мне нужен ответ: я дурак, или это c++ подвел (естественно первое:)). Я решил...

8
Комп_Оратор)
Эксперт по математике/физике
8949 / 4703 / 629
Регистрация: 04.12.2011
Сообщений: 13,999
Записей в блоге: 16
13.12.2015, 11:14 2
Лучший ответ Сообщение было отмечено anti-k как решение

Решение

anti-k, может new/delete повторить? В том смысле, что delete к автоматической переменной, это что? И если создадите динамический объект то создайте его в отдельной области. В функции которая вызовется из main, например. Или вставьте в деструктор задержку после cout (сin.get() например) иначе реакции может не хватить.
1
227 / 75 / 31
Регистрация: 17.07.2015
Сообщений: 774
13.12.2015, 11:20  [ТС] 3
IGPIGP,
Я мало что понял, но сделаю как советуете, может откроется
0
Комп_Оратор)
Эксперт по математике/физике
8949 / 4703 / 629
Регистрация: 04.12.2011
Сообщений: 13,999
Записей в блоге: 16
13.12.2015, 11:24 4
Цитата Сообщение от anti-k Посмотреть сообщение
Я мало что понял,
Попытка освободить память из под стековой переменной это жесть. Если не поняли то + к new/delete почитайте самую общую информацию о стеке, времени жизни переменных различного класса хранения и т.п. Иначе не поймёте.
0
227 / 75 / 31
Регистрация: 17.07.2015
Сообщений: 774
13.12.2015, 11:33  [ТС] 5
IGPIGP, Добавил cin.get() в деструктор. Удивительные вещи!!!
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
#include<cstring>
using namespace std;
template<typename T>
class smartpointer
{
public:
    smartpointer(T*ob) :sp(ob) { cout << "\npointer created\n"; }
    smartpointer(T&&ob) :sp(ob.aka) { ob.aka = nullptr; cout << "moved"; }
    ~smartpointer() { delete sp; cout << "\npointer deleted\n"; }
    T*operator->() { return sp; }
    T&operator*() { return *sp; }
private:
    T*sp;
 
};
//template<typename t>
class tralala
{
public:
    tralala():aka(nullptr) { cout << "\nempty object created\n"; }  
    tralala(char*g) :aka(new char[strlen(g) + 1]) { strcpy(aka, g); cout << "\ninittialized object created\n"; }
    void Print() { cout << aka << endl; }
    ~tralala() { cin.get(); delete[] aka; cout << "\naka deleted\n"; }
private:
    char*aka;
};
int main()
{
    tralala one("trololo");
    one.Print();
    {
        //smartpointer<tralala>pn(new tralala(one));
        smartpointer<tralala>pn(new tralala(one));
        pn->Print();
    }
    
    cout << "**************\n";
    one.Print();
 
 
    return 0;
}
1.Создает tralala затем smartpointer 2.ждет ввода 3.вызывает деструктор для tralala и для smartpointer(все как положено в обратном порядке)3.ОПЯТЬ ЖДЕТ ВВОД!!!(здесь совсем не понятно) и затем крэш.
Сеньор IGPIGP , помогите разобраться, не первый день мучаюсь с этим смартом

Добавлено через 1 минуту
IGPIGP, Не успел прочесть ваш коммент сейчас разберусь где там стэковая переменная

Добавлено через 1 минуту
C++
1
2
3
4
5
6
7
8
9
10
    tralala one("trololo");//создается объект с new полем
    one.Print();
    {
        //smartpointer<tralala>pn(new tralala(one));
        smartpointer<tralala>pn(new tralala(one));опять таки new!!
        pn->Print();
    }
    
    cout << "**************\n";
    one.Print();
Где стековая переменная?
0
Комп_Оратор)
Эксперт по математике/физике
8949 / 4703 / 629
Регистрация: 04.12.2011
Сообщений: 13,999
Записей в блоге: 16
13.12.2015, 11:43 6
Про стековую, это я не вчитался. А про задержку верно. Вот формально следуя Вашей логике:
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
#include <string>
using namespace std;
 
template<class T>
struct Sp
{
T* sp;
Sp(const T& rhs)
{
cout<<"new"<<endl;
sp=new T(rhs);
cin.get();
}
~Sp()
{
cout<<"delete!"<<endl;
delete sp;
cin.get();
}
T*operator->() { return sp; }
T&operator*() { return *sp; }
};
struct Lol
{
string lol;
Lol(){lol="";}
Lol(const char *rhs):lol(rhs){cout<<"create Lol"<<endl;
cin.get();}
~Lol()
{
cout<<"destroy Lol!"<<endl;
cin.get();
 
}
};
void foo(Lol lol)
{
Sp<Lol> sp(lol);
}
 
int main(){
Lol lol("lol");
foo(lol);
cout<<endl;
system("pause"); 
    return 0; 
}
1
227 / 75 / 31
Регистрация: 17.07.2015
Сообщений: 774
13.12.2015, 13:21  [ТС] 7
IGPIGP,Я решил!! дело было в том что яне перегрузил конструкторы копии!!!!
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
62
63
64
65
66
67
68
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<cstring>
using namespace std;
 
 
class tralala
{
public:
    tralala() :name(nullptr) { cout << "\nempty created\n"; }
    tralala(const char*tmp) :name(new char[strlen(tmp) + 1]()) { strcpy(name, tmp); cout << "\created by NEW!!!\n"; }
    tralala(tralala&ob)
    {
        if (name)
            delete name;
        name = new char[strlen(ob.name) + 1]();
        strcpy(name, ob.name);
        cout << "\nCOPIED\n";
    }
    tralala(tralala&&ob)
    {
        if (name)
            delete name;
        name = ob.name;
        ob.name = nullptr;
        cout << "\nMOVED\n";
 
    }
    tralala&operator=(tralala&ob)
    {
        if (name)
            delete name;
        name = new char[strlen(ob.name) + 1]();
        strcpy(name, ob.name);
    }
    void Print() { cout << "\n" << name << "\n"; }
    ~tralala() { delete name; cout << "\n Name deleted\n";
    }
 
private:
    char*name;
 
};
template<typename T>
class smartpoint
{
public:
    smartpoint(T*obj)
        : n(obj) {
        cout << "\Pointer created\n";
    }
    T*operator->() { return n; }
    T& operator* () { return *n; }
    ~smartpoint() { delete n; cout << "pointer deleted\n"; }
 
private:
    T*n;
 
};
int main()
{
    tralala a("Anton");
    a.Print();
    smartpoint<tralala> aa(new tralala(a));
 
 
    return 0;
}
Спасибо за помощь!!!
0
Комп_Оратор)
Эксперт по математике/физике
8949 / 4703 / 629
Регистрация: 04.12.2011
Сообщений: 13,999
Записей в блоге: 16
23.12.2015, 16:57 8
Лучший ответ Сообщение было отмечено anti-k как решение

Решение

anti-k, я там спросонок наговорил бог знает что. Почувствовав угрызения совести, вспомнил, что когда-то пытался написать ну очень простой умныйленивый) указатель на базе std::map. Но не дописал. Сейчас раскопал, доделал кое-как. Поглядите, может пригодится.

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

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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
//SmartPtrIgP.h
using std::map;
using std::pair;
template<class T>
class Sp;
 
template<class T>
class GC
{
private:
friend class Sp<T>;
std::map< T*, pair<int /*cnt*/, int /*siz*/>> mapa;//array pointers
GC(){}
 GC( const GC&);  
    GC& operator=( GC& );
 
    static GC& getInstance() {
        static GC  instance;
        return instance;
    }
 void Add(T *rhs)
{
if( mapa.empty())return;
 
map< T*, pair<int,int>>:: iterator fnd=mapa.end();
    fnd=mapa.find(rhs);
    if(fnd != mapa.end())
    {
        ((*fnd).second).first++;
    }
}
void Add(const T *rhs)
{
Add(rhs);
}
void AddNew(T *rhs,int sz)
{
    pair<int, int > prVal(0, sz);
    pair<T*, pair<int, int >> pr(rhs,prVal);
    mapa.insert(pr);    
}
void AddNew(const T *rhs, int sz)
{
    AddNew(rhs, sz);            
}
bool remove(T *rhs)
{
bool is_empty=false;
if(mapa.empty())return !is_empty;
 
map< T*, pair<int,int>>:: iterator fnd;
    fnd=mapa.find(rhs); 
    if(fnd != mapa.end())
    {
((*fnd).second).first--;
if(((*fnd).second).first==0)
{
    is_empty=true;
T *toDel=(*fnd).first;
int sz=((*fnd).second).second;
if(sz==1)delete toDel;
else delete [] toDel;
mapa.erase(fnd);
}
    }
return is_empty;
}
 
public:
T *operator()(const T &rhs)
{
T *ptr = new T(rhs);
AddNew(ptr,1);
return ptr;
}
T *operator[](int rhs)
{
T *ptr = new T[rhs];
AddNew(ptr, rhs);
return ptr;
}
 
void print_map()
        {
cout<<"\n____________pointers_to_arrays__________________\n";
map< T*, pair<int,int>>:: iterator ita=mapa.begin();
for(;ita!=mapa.end();++ita)
{
    cout<<(*ita).first<<" "<<((*ita).second).first<<endl;
}
}
size_t get_size(T *rhs)
{
size_t  ret=0;
if( mapa.empty())return ret;
map< T*, pair<int,int>>:: iterator fnd=mapa.end();
    fnd=mapa.find(rhs);
    if(fnd != mapa.end())
    {
        ret=((*fnd).second).second;     
    }
return ret;
}
};
 
template<class T>
class Sp
{
friend class GC<T>;
T *ptr;
public:
static GC<T> &NEW;
int PointersInDataBase()const
{
return NEW.mapa.size();
}
void ptintPtrDBsize()const
{
cout<<endl<<"PointersInDataBase size= "<<PointersInDataBase()<<endl;
}
~Sp()
{
NEW.remove(ptr);
}
 
Sp()
{
ptr=NULL;
}
Sp(const T &rhs)
{
ptr =const_cast<T*>(&rhs);
NEW.Add(ptr);
}
Sp(T &rhs)
{
ptr = &rhs;
NEW.Add(ptr);
}
 
Sp(const T *rhs)
{
ptr = const_cast<T*>(rhs);
NEW.Add(ptr);
}
 
Sp(T *const rhs)
{
ptr = rhs;
NEW.Add(ptr);
}
 
Sp(const Sp &rhs)
{
ptr = rhs.ptr;
NEW.Add(ptr);
}
 
Sp &operator=(const Sp &rhs)
{
NEW.remove(ptr);
ptr=rhs.ptr;
NEW.Add(ptr);
return *this;
}
 
Sp &operator=(T * rhs)
{
if(this.ptr==rhs)return *this;
NEW.remove(ptr);
ptr=const_cast<T*>(rhs);
NEW.Add(ptr);
return *this;
}
const T *operator->()const{return ptr;}
const T &operator*()const{return *ptr;}
T &operator[](int ind){return *(ptr+ind);}
size_t get_size()
{
size_t  ret=0;
ret=NEW.get_size(ptr);
return ret;
}
 
void printVal()
{
size_t sz_ptr=NEW.get_size(ptr);
for(size_t i=0; i<sz_ptr; ++i)
{   
cout<<ptr[i]<<endl;
}
if(!sz_ptr)cout<<*ptr<<endl;
}
};
 
template<typename T>
GC<T> &Sp<T>::NEW= GC<T>::getInstance();//статический экземпляр синглтона Маерса)

//main.cpp
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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#include<iostream>
#include<map>
#include"SmartPtrIgP.h"
#include <vector>
#include <algorithm>
#include <ctime>
//тест класса Sp<T> - указатель с признаками интеллекта,
//со сборщиком реализованным на std::map
//то есть - ну оч-чень ленивый указатель)
using namespace std;
struct A
{
int n;
static bool isExpressed;
static int cnt;
static int del;
static const int N=10000;
double myArray[N];
 
void arrInit()
{
for(int i=0; i<N; i++)
myArray[i]=i;
}
void arrInit(const double *a)
{
for(int i=0; i<N; i++)
myArray[i]=a[i];
}
 
A()
{
cnt++;
n=0;
arrInit();
if(isExpressed) cout<<"A()"<<cnt<<endl;
}
 
A(const int a)
{
cnt++;
n=a;
arrInit();
if(isExpressed)cout<<"A(const int)"<<cnt<<endl;
}
 
A(const A &a)
{
cnt++;
n=a.n;
arrInit(a.myArray);
if(isExpressed)cout<<"A(const A&)"<<cnt<<endl;
}
~A(){
    del++;
    if(isExpressed)cout<<"~A()"<<del<<endl;
}
int operator<(const A &rhs)const
{
return n<rhs.n;
}
};
int A::cnt=0;
int A::del=0;
bool A::isExpressed=true;
 
 
 
int compireByPtr(Sp<A> lhs, Sp<A> rhs)
{
return *lhs<*rhs;
}
 
void localOperationalScope()
{
const int size=1000;
A::isExpressed =false;
A *arr = new A[size];
srand((unsigned)time(NULL));
for(int i=0;i<size;i++){
    arr[i].n=rand()%(size-1);
}
vector<A> first;
for(int i=0;i<size;i++)first.push_back(arr[i]);
for(int i=0;i<size;i++)cout<<first[i].n<<" ";
cout<<endl;
 
clock_t tBegFirst=clock();
sort(first.begin(), first.end());
clock_t  tEndFirst=clock ();
clock_t spanF= tEndFirst-tBegFirst;
 
for(int i=0;i<size;i++)cout<<first[i].n<<" ";
cout<<endl;
cout<<"first elapsed "<<spanF<<endl;
 
vector<Sp<A>> second;
for(int i=0;i<size;i++)
    second.push_back(Sp<A>(arr[i]));
 
clock_t tBegSecond=clock();
sort(second.begin(), second.end(),compireByPtr);
clock_t tEndSecond=clock();
clock_t spanS=tEndSecond-tBegSecond;
cout<<"second elapsed "<<spanS<<endl;
for(int i=0;i<size;i++)cout<<second[i]->n<<" ";
cout<<"\nfirst processing takes "<<(float)spanF/spanS<<" times more time than second"<<endl;
cout << endl;
}
 
int main()
{
    localOperationalScope();
    cout<<"Количество указателей в базе после возврата:"<<endl;
    Sp<A> sp_last;//это для вызова метода ptintPtrDBsize()
    //но любой локальный указатель не указывающий на динамическую память
    //выделенную классом Sp не попадает в базу
    sp_last.ptintPtrDBsize();
 
cin.get();
return 0;
}


Вот кусочек показывающий как с динамической памятью работает.
Кликните здесь для просмотра всего текста

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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
//тест с выделением динамической памяти
struct ValType
{
string mess_str;
ValType()
{
mess_str="default";
}
ValType(const char* c_str)
{
mess_str=c_str;
}
ValType(const ValType &rhs)
{
mess_str=rhs.mess_str;
}
friend ostream & operator<<(ostream &os, const ValType &val);
 
};
 
ostream & operator << (ostream &os, const ValType &val)
{
os<<val.mess_str;
return os;
}
 
Sp<ValType>  foo(const ValType vt)
{   
const Sp<ValType> sp_loc=&vt;
Sp<ValType> sp_dynamic1=Sp<ValType>::NEW(vt);
Sp<ValType> sp_loc_dynamic1=sp_dynamic1;
Sp<ValType> sp_loc_dynamic2=sp_dynamic1;
Sp<ValType> sp_dynamic2=Sp<ValType>::NEW(vt);
Sp<ValType> sp_dynamic3=Sp<ValType>::NEW(vt);
Sp<ValType> sp_dynamic4=Sp<ValType>::NEW(vt);
cout<<"before array ";
sp_loc.ptintPtrDBsize();
Sp<ValType> sp_dynamic_array=Sp<ValType>::NEW[10];
cout<<"sp_dynamic_array.get_size()= "<<sp_dynamic_array.get_size()<<endl;
Sp<ValType> sp_loc_dynamic5=sp_dynamic_array;//локальный указатель установлен на
//созданный массив, - проверка) работает нормально
cout<<"sp_loc_dynamic5.get_size()= "<<sp_loc_dynamic5.get_size()<<endl;
string n="0";
for(size_t i=0; i<sp_dynamic_array.get_size(); ++i)//задаём значенияобъектов в массиве
{
    n[0]='0'+i;
    sp_dynamic_array[i].mess_str="mess "+n;
}
cout<<endl<<endl;
sp_dynamic_array.printVal();//печатаем что получилось
cout<<"\nFinnaly before return and destructors call:"<<endl;
sp_loc.NEW.print_map();
cout<<"before return"<<endl;
sp_loc.ptintPtrDBsize();
return sp_loc_dynamic5;
}
 
int main()
{
 
 
 
ValType vt("Obj");
const Sp<ValType> sp_loc=&vt;
sp_loc.ptintPtrDBsize();
cout<<"befor the call"<<endl;
Sp<ValType> sp_loc1=foo(vt);//локальный указатель становится массивом
//то есть старое значение удаляется и создаётся новое
cout<<"after return"<<endl;
sp_loc1.printVal();
sp_loc.NEW.print_map();
sp_loc.ptintPtrDBsize();
system("pause");
return 0;
}
1
227 / 75 / 31
Регистрация: 17.07.2015
Сообщений: 774
23.12.2015, 18:06  [ТС] 9
IGPIGP, Конечно пригодиться!!!
0
23.12.2015, 18:06
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
23.12.2015, 18:06
Помогаю со студенческими работами здесь

Реализовать пользовательский класс Matrix (найти причины возникновения ошибок в коде и исправить эти ошибки)
Доброго времени суток,задание написать класс Matrix,все вроде бы понятно,но почему-то моя матрица...

Реализовать пользовательский класс "Связанный список" (не понимаю код)
Всем привет , может кто рассказать конкретно что происходит в тех строках где стоят комментарии....

Реализовать пользовательский класс Pair (упрощённый аналог std::pair)
Здравствуйте. Проблема с выводом. В приложенном задании, требуется сделать вывод как в примере. Мой...

Реализовать пользовательский класс "Математический вектор"
Мне нужно написать програму которая будет делать разные операции над векторами, используя...

Реализовать пользовательский класс "Список" и функции-члены для создания, просмотра и удаления списка
Добрый день. Имеются несколько функций для работы с однонаправленным списком. Не получается...

Реализовать пользовательский класс "Список"
Нужна помощь с заданием по спискам, вот само задание: 12. Создать линейный односвязный...

Реализовать пользовательский класс "Список"
Помогите, немогу понять как делать список в ооп на с++, если можно примеры.


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

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

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