Всем доброго времени суток. Уже в третий раз обращаюсь к форумчанам за помощью по этой лабораторной работе. Начать читать про
RAII и
умные указатели, и начал тупить.
Где застрял: Есть класс
User, есть класс умного указателя
SmartPointer, в функции main есть вектор, который на данный момент содержит "пользователей". Хотелось бы как-то это все передать, чтобы вектор содержал умные указатели на пользователя с подсчетом ссылок,
то есть, когда счетчик равен единице мы смело удаляем объект (пользователя). Так же меня терзают смутные сомнения, что будут возникать проблемы, если кинуть какое-нибудь исключение. Поэтому прошу помочь всех желающих.
Среда разработки: CodeBlocks 12.11.
Заголовок класса "Пользователь".
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
| #ifndef MYSKYPE_H
#define MYSKYPE_H
#include <string>
using namespace std;
class User
{
private:
int id, friend_number, ban_number;
string nickname, password, email;
User *friend_list, *ban_list;
public:
User();
User(int identifier, int numF, int numB, string nick, string pasw, string mail, User *frd, User *ban);
User(const User &original);
~User();
int get_id();
int get_friend_number();
int get_ban_number();
string get_nick();
string get_pasw();
string get_mail();
void put_id(int identifier);
void put_friend_number(int numF);
void put_ban_number(int numB);
void put_nick(string name);
void put_pasw(string psw);
void put_mail(string mail);
};
#endif |
|
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
| #ifndef SPOINTER_H
#define SPOINTER_H
template<typename T>
class SmartPointer
{
private:
T *my_obj;
int *counter; // Указатель на число. Чтобы счетчик был общим
public:
SmartPointer(T *obj): // Отдаем ему во владение некий объект
my_obj(obj),
counter(0)
{}
~SmartPointer() // По выходу из области видимости этот объект мы уничтожим
{
*counter = *counter - 1;
if(*counter == 1)
delete my_obj;
}
T* operator->() // Обращение к данным типа T посредством "стрелочки"
{
return my_obj;
}
T& operator* () // С помощью такого оператора мы можем разыменовать указатель и получить ссылку на объект, который он хранит
{
return *my_obj;
}
};
#endif |
|
функция main.
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
| #include "myskype.h"
#include "spointer.h"
#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
#include <vector>
using namespace std;
void show_user_list(vector<User> &a, int size) // & - по ссылке, если нужно изменять внешний вектор array
{
cout << "All members of our network:\n\n";
for(int i = 0; i < size; ++i)
{
cout << "Id:" << a[i].get_id() << " ";
cout << "Nickname:" << a[i].get_nick() << " ";
cout << "Password:" << a[i].get_pasw() << " ";
cout << "Email:" << a[i].get_mail() << " ";
cout << endl << "Friends:" << a[i].get_friend_number() << " ";
cout << "Ban:" << a[i].get_ban_number() << endl << endl;
}
}
int main()
{
vector<User> vcr(3);
User *network;
network = new User[3];
string line;
string helper;
int file_id = 0;
int file_num_frd = 0;
int file_num_ban = 0;
int counter = 0;
string file_nick;
string file_pasw;
string file_mail;
ifstream userfile("user.txt");
if (userfile.is_open())
{
for(int i = 0; !userfile.eof(); ++i)
{
getline(userfile, line);
helper = line;
helper += " ";
getline(userfile, line);
helper += line;
helper += " ";
getline(userfile, line);
helper += line;
helper += " ";
istringstream ist(helper);
ist >> file_id >> file_num_frd >> file_num_ban;
ist.clear();
getline(userfile, line);
file_nick = line;
getline(userfile, line);
file_pasw = line;
getline(userfile, line);
file_mail = line;
network[i].put_id(file_id);
network[i].put_nick(file_nick);
network[i].put_pasw(file_pasw);
network[i].put_mail(file_mail);
network[i].put_friend_number(file_num_frd);
network[i].put_ban_number(file_num_ban);
++counter;
}
userfile.close();
}
else cout << "Unable to open file!" << endl;
for(int i = 0; i < counter; ++i)
vcr[i] = network[i];
show_user_list(vcr, counter);
delete []network;
return 0;
} |
|
Добавлено через 9 минут
Правда может возникнуть неловкая ситуация, если пользователи находятся в друзьях у друг друга. Тогда при удаление одного пользователя возникнет ошибка. Преподаватель посоветовал использовать слабые указатели, но я его уговорил пусть лучше все пользователи будут оригинальными.
Добавлено через 24 минуты
Читал на хабре про реализацию смарт поинтера и застрял на примере с библиотекой буст.
См. здесь: http://habrahabr.ru/post/140222/
Добавлено через 10 минут
В той же статье на хабре наткнулся на, вроде как, стандартную библиотеку реализующую умный указатель с подсчетом ссылок
std::shared_ptr (С++11).
#include <memory> // либо <tr1/memory> для компиляторов, еще не поддерживающих C++11