Форум программистов, компьютерный форум CyberForum.ru

Колода карт (тусовка и освобождение памяти) - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 13, средняя оценка - 4.69
nexen
187 / 180 / 3
Регистрация: 27.01.2012
Сообщений: 1,335
29.06.2012, 12:07     Колода карт (тусовка и освобождение памяти) #1
Собственно столкнулся с двумя вопросами :
1) Каким образом перетусовать колоду карт? Ничем путнее, чем умножить кол-во карт на 8 (N) и менять местами две рандомные карты N-раз не придумал..
2) Сама колода содержит два поля :
C++
1
2
int _cnt; // count
_Card* stack; //массив карт
Если я переписываю деструктор и удаляю колоду так :
C++
1
2
3
4
~_Pack()
{
delete [] stack;
}
То получается, что переменная _cnt не удалена из памяти, ведь деструктор, который вызывается по умолчанию я переопределил. Как удалить обычную (не указатель/массив) переменную?

p.s Бонус вопрос :
Почему не прокатывает со стандартным std?
C++
1
val += (((int)_val == 10) ? "10" : _val); // где _val - char
Но работает :
C++
1
2
val += _val;
val += "10";
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
29.06.2012, 12:07     Колода карт (тусовка и освобождение памяти)
Посмотрите здесь:

C++ Освобождение памяти
Колода карт C++
резервирование памяти/освобождение памяти для трехмерного массива C++
Колода карт C++
Клас колода карт C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
rescr1pt
31 / 32 / 1
Регистрация: 03.10.2011
Сообщений: 61
29.06.2012, 14:37     Колода карт (тусовка и освобождение памяти) #2
Используй функцию из стандартной библиотеки: random_shuffle

Например:
Откопал свой старый проект, вот как я тасую карты:
C++
1
2
3
4
5
6
7
void Deck::Shuffle()
{
    std::vector<Card*> vCards(m_cards.begin(), m_cards.end());
    std::random_shuffle(vCards.begin(), vCards.end());
    m_cards.assign(vCards.begin(), vCards.end());
    vCards.erase(vCards.begin(), vCards.end());
}
Добавлено через 5 минут
Цитата Сообщение от nexen Посмотреть сообщение
То получается, что переменная _cnt не удалена из памяти, ведь деструктор, который вызывается по умолчанию я переопределил. Как удалить обычную (не указатель/массив) переменную?
Переменная будет удалена из памяти при выходе за пределы ее видимости.
nexen
187 / 180 / 3
Регистрация: 27.01.2012
Сообщений: 1,335
29.06.2012, 18:42  [ТС]     Колода карт (тусовка и освобождение памяти) #3
Цитата Сообщение от rescr1pt Посмотреть сообщение
Используй функцию из стандартной библиотеки: random_shuffle

Например:
Откопал свой старый проект, вот как я тасую карты:
C++
1
2
3
4
5
6
7
void Deck::Shuffle()
{
    std::vector<Card*> vCards(m_cards.begin(), m_cards.end());
    std::random_shuffle(vCards.begin(), vCards.end());
    m_cards.assign(vCards.begin(), vCards.end());
    vCards.erase(vCards.begin(), vCards.end());
}
Добавлено через 5 минут

Переменная будет удалена из памяти при выходе за пределы ее видимости.
Т.е, если у меня есть некоторый экземпляр класса в функции main (допустим, это некоторая "временная" переменная), я использовал её для (допустим) swap'а, а затем хочу удалить её с концами, чтобы больше не было вообще такого идентификатора и я спокойно смог после некоторой команды снова использовать её идентификатор, то я ничего с этим вообще не поделаю, ведь она описана в main?
{За тусовку большое спасибо. Даже и не думал, что такое в stl реализовано, правда мне не понятно, почему rand() у них нормально срабатывает без srand(time(NULL))}

p.s Всё ещё интересен ответ на третий вопрос про string

Добавлено через 2 часа 38 минут
Помогите, пожалуйста? ;(

Добавлено через 35 минут
Так же хочу узнать, почему может быть такое :
_Pack temp = myPack; // temp-указатель _Card* stack; указывает туда же, куда и myPack

а при :
_Pack temp;
temp = myPack; // все нормально. Правильно проработала перегрузка "=".

Конструктор выглядит так : _Pack() : _cnt(0), _stack(0) {}, поэтому проблем быть не должно с ним :<
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
29.06.2012, 18:59     Колода карт (тусовка и освобождение памяти) #4

Не по теме:

Тусовка карт - это сильно. С какого достоинства пускают на эту тусу?


C++
1
val += (((int)_val == 10) ? "10" : _val); // где _val - char
Тернарный оператор не работает с разными типами результатов.
igorrr37
 Аватар для igorrr37
1593 / 1221 / 118
Регистрация: 21.12.2010
Сообщений: 1,868
Записей в блоге: 7
29.06.2012, 19:00     Колода карт (тусовка и освобождение памяти) #5
Цитата Сообщение от nexen Посмотреть сообщение
Всё ещё интересен ответ на третий вопрос про string
операнды должны быть одного типа:
"10" - const char*
_val - char
nexen
187 / 180 / 3
Регистрация: 27.01.2012
Сообщений: 1,335
29.06.2012, 19:03  [ТС]     Колода карт (тусовка и освобождение памяти) #6
Хоу, не подумал об этом даже > _ <"

Остался последний вопрос. Продублирую на всякий :
Так же хочу узнать, почему может быть такое :
_Pack temp = myPack; // temp-указатель _Card* stack; указывает туда же, куда и myPack

а при :
_Pack temp;
temp = myPack; // все нормально. Правильно проработала перегрузка "=".

Конструктор выглядит так : _Pack() : _cnt(0), _stack(0) {}, поэтому проблем быть не должно с ним :<
igorrr37
 Аватар для igorrr37
1593 / 1221 / 118
Регистрация: 21.12.2010
Сообщений: 1,868
Записей в блоге: 7
29.06.2012, 19:10     Колода карт (тусовка и освобождение памяти) #7
_Pack temp = myPack; - здесь вызывается конструктор копии
nexen
187 / 180 / 3
Регистрация: 27.01.2012
Сообщений: 1,335
29.06.2012, 19:42  [ТС]     Колода карт (тусовка и освобождение памяти) #8
Цитата Сообщение от igorrr37 Посмотреть сообщение
_Pack temp = myPack; - здесь вызывается конструктор копии
Но чем ему так помешал конструктор с обнулением?
И разве в данном случае вызывается не связка в порядке : конструктор, присваивание?

Добавлено через 15 минут
При этом если я просто закомменчиваю свой конструктор, происходит то же самое ;<

Добавлено через 15 секунд
При этом если я просто закомменчиваю свой конструктор, происходит то же самое ;<

Добавлено через 12 минут
Так же, даже если у меня имеется такой вариант :
C++
1
2
_Pack temp;
 temp = myPack;
Деструктор выбрасывает ошибку при разрушении второго объекта.
C++
1
2
3
4
~_Pack()
    {
        delete[] _stack;
    }
Вот собственно оператор равно :
C++
1
2
3
4
5
6
7
8
9
void operator = (_Pack cur)
    {
        _cnt = cur._cnt;
        int n = _cnt;
        _Card* stack = new _Card[n];
        _stack = stack;
        while((--n) >= 0)
            stack[n] = cur._stack[n];
    }
igorrr37
 Аватар для igorrr37
1593 / 1221 / 118
Регистрация: 21.12.2010
Сообщений: 1,868
Записей в блоге: 7
29.06.2012, 20:18     Колода карт (тусовка и освобождение памяти) #9
оператор= принимает объект по значению - вызывается конструктор копии, после - деструктор этой копии, если конструктор копии дефолтный, то будет вызван delete для объекта myPack. Мораль - нужно перегрузить конструктор копии.
nexen
187 / 180 / 3
Регистрация: 27.01.2012
Сообщений: 1,335
29.06.2012, 20:37  [ТС]     Колода карт (тусовка и освобождение памяти) #10
Цитата Сообщение от igorrr37 Посмотреть сообщение
оператор= принимает объект по значению - вызывается конструктор копии, после - деструктор этой копии, если конструктор копии дефолтный, то будет вызван delete для объекта myPack. Мораль - нужно перегрузить конструктор копии.
Отлично, спасибо. Как-то даже и не знал про конструкторы копии -_-"

Но теперь другой вопрос >
Есть ли возможность избежать тупого копипаста кода перегрузки операции = :
C++
1
2
3
4
5
6
7
8
9
_Pack(_Pack& cur)
    {
        _cnt = cur._cnt;
        int n = _cnt;
        _Card* stack = new _Card[n];
        _stack = stack;
        while((--n) >= 0)
        stack[n] = cur._stack[n];
    }
и использовать уже имеющуюся, чтобы сделать красивенький :
C++
1
2
3
4
_Pack(_Pack& cur)
    {
        *this = cur;
    }
?
Понятное дело, что так оно не пройдет, ибо зациклится при вызове конструктора копии из оператора, но всё же (может быть) есть способ? :<
igorrr37
 Аватар для igorrr37
1593 / 1221 / 118
Регистрация: 21.12.2010
Сообщений: 1,868
Записей в блоге: 7
30.06.2012, 04:45     Колода карт (тусовка и освобождение памяти) #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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#include <iostream>
#include <algorithm>
 
struct Card
{
    char suit;
    int value;
};
 
class Pack
{
public:
    Pack() : p(nullptr), size(0){}
    Pack(Pack const& rhs) : size(rhs.size), p(new Card[rhs.size])
    {
        std::copy(rhs.p, rhs.p + size, p);
    }
    Pack(Card const& c) : p(new Card[1]), size(1)
    {
        p[0] = c;
    }
    Pack& operator=(Pack const& rhs)
    {
        if(this != &rhs)
        {
            Pack tmp = rhs;
            this->~Pack();
            size = tmp.size;
            std::swap(p, tmp.p);
        }
        return *this;
    }
    ~Pack()
    {
        delete[] p;
        p = nullptr;
    }
//private:
    Card* p;
    std::size_t size;
};
 
int main()
{
    Card c{'s', 11};
    Pack p(c), p1;
    p1 = p;
    std::cout << p.p << '\n' << p1.p << '\n' << p1.p[0].value << '\n';
    return 0;
}
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
30.06.2012, 14:10     Колода карт (тусовка и освобождение памяти) #12
igorrr37, Да можно и полностью copy_swap организовать, т.е. каноническую форму.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
30.06.2012, 17:13     Колода карт (тусовка и освобождение памяти)
Еще ссылки по теме:

C++ Освобождение памяти в C++
C++ Колода карт, считать данные из файла в кодировке Unicode
C++ Создать класс "Колода карт"

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

Или воспользуйтесь поиском по форуму:
igorrr37
 Аватар для igorrr37
1593 / 1221 / 118
Регистрация: 21.12.2010
Сообщений: 1,868
Записей в блоге: 7
30.06.2012, 17:13     Колода карт (тусовка и освобождение памяти) #13
copy-and-swap вкупе с copy elision дают на выходе unifying assignment operator
C++
1
2
3
4
5
6
7
8
9
10
Pack& operator=(Pack rhs)
{
    rhs.Swap(*this);
    return *this;
}
void Swap(Pack& rhs)
{
    std::swap(p, rhs.p);
    std::swap(size, rhs.size);
}
Yandex
Объявления
30.06.2012, 17:13     Колода карт (тусовка и освобождение памяти)
Ответ Создать тему
Опции темы

Текущее время: 18:07. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru