Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.89/19: Рейтинг темы: голосов - 19, средняя оценка - 4.89
 Аватар для Kastaneda
5232 / 3205 / 362
Регистрация: 12.12.2009
Сообщений: 8,143
Записей в блоге: 2

Кому интересно поломать голову

31.01.2015, 11:51. Показов 4042. Ответов 63
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Привет!

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

Предлагаю вам подумать в как и когда может работать данный код (выкладываю именно в том контексте, в который я смотрел, больше не скажу, не интересно будет)

C++
1
2
3
4
5
//где-то в классе
typedef std::set<ClassOne, ClassTwo> _Container;
 
// где-то в методе
return std::find(_Container::begin(), _Container::end(), predicate);
Если кто-то раскусит за 5 секунд, значит я переработал. Я реально минут 5 сидел в это втыкал
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
31.01.2015, 11:51
Ответы с готовыми решениями:

Кому интересно. Покер
Вообщем, давно ничего не кодил и на днях накатал немного говно кода на тему Покера. Кому будет интересно, посмотрите и предложите если...

Бинарные деревья ! кому интересно , сюда!;)
задание : Описать процедуру или функцию которая : а) печатает запись, встречающуюся в дереве один раз б) печатает запись,...

прога странно работает=) кому интересно покопать?
написал прогу по подсчету crc-16 (сама функция с википедии).. так вот... когда скармливаю файл (текстовыми кормлю) на несоклько килобайт (1...

63
419 / 418 / 72
Регистрация: 27.05.2012
Сообщений: 1,168
02.02.2015, 22:21
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от hoggy Посмотреть сообщение
Кроме того, предположим адаптер должен представлять собой "почти такой же" вектор,
изменена лишь логика oparetor[].
ты похоже совершенно не в курсе как работают stack и queue


Цитата Сообщение от hoggy Посмотреть сообщение
Итого:
При наследовании: минимум работы:
определяем только необходимое.
новые плюшки подхватываются автоматически.
При композиции: максимум работы:
определяем даже то, что не нуждается в изменении.
новые плюшки добавляются только вручную.
давай ка посмотрим на простейшие, но достаточные, имеется ввиду интерфейс, реализации стэка

наследование
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
#include <iostream>
#include <deque>
 
template<typename T, class Container = std::deque<T, std::allocator<T>>>
class Stack : public Container
{
    using size_type = typename Container::size_type;
    using value_type = typename Container::value_type;
    using reference = typename Container::reference;
    using const_reference = typename Container::const_reference;
public:
    bool empty() const { return Container::empty(); }
    size_type size() const { return Container::size(); }
    value_type& top() { return Container::back(); }
    const value_type& top() const { return Container::back(); }
    void push(const value_type& val) { Container::push_back(val); }
    void pop() { Container::pop_back; }
private:
    void clear();
    template <class InputIterator>
    void assign (InputIterator first, InputIterator last);
    void assign (size_type n, const value_type& val);
    reference at (size_type n);
    const_reference at (size_type n) const;
    reference front();
    const_reference front() const;
    //... и закрыть кучу остальных функций членов std deque чтобы это таки стал стэк!
};
 
int main() 
{
    Stack<int> st;
    st.push(2);
    std::cout << st.empty() << std::endl;
    //st.std::deque<int>::clear(); // но прикинь - такой онанизм будет работать!
    std::cout << st.top() << std::endl;
    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
#include <iostream>
#include <deque>
 
template<typename T, class Container = std::deque<T, std::allocator<T>>>
class Stack
{
    using size_type = typename Container::size_type;
    using value_type = typename Container::value_type;
    using reference = typename Container::reference;
    using const_reference = typename Container::const_reference;
    
    Container m_container;
public:
    bool empty() const { return m_container.empty(); }
    size_type size() const { return m_container.size(); }
    value_type& top() { return m_container.back(); }
    const value_type& top() const { return m_container.back(); }
    void push(const value_type& val) { m_container.push_back(val); }
    void pop() { m_container.pop_back; }
};
 
int main() 
{
    Stack<int> st;
    st.push(2);
    std::cout << st.empty() << std::endl;
    std::cout << st.top() << std::endl;
    return 0;
}
при закрытом наследовании кода будет столько же как и при композиции - почти один в один
0
02.02.2015, 22:31

Не по теме:

Кудаив, using-и всё таки наверное в public...

0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
02.02.2015, 22:40
Цитата Сообщение от gray_fox Посмотреть сообщение
hoggy, можно закрытое наследование; писать правда всё равно больше, чем при открытом (и надо будет дописывать при изменении интерфейса адаптируемого класса)
Ага. Но в этом случае все равно в разы меньше, чем при композиции.
Потому что не нужно полностью описывать все прототипы c делегирующей реализацией.
Достаточно просто перечислить списки того, что хочется переиспользовать:

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 <iostream>
 
struct vector
{
    size_t size()const { return 0; }
    
    void reserve(const size_t) {}
};
 
struct der: protected vector //<--- суть: der не является vector, 
{                          //хотя и умеет все, что умеет vector  
    
    // просто указываем, что хотим переиспользовать
    using vector::vector;
    using vector::size;
    
    
};
 
 
void foo(vector&){}
 
int main()
{
    std::cout << "Hello, world!\n";
    
 
 
    // error: ‘vector’ is an inaccessible base of ‘der’    
    // поскольку der не является vector, то полиморфизм запрещен
    // vector* ololo = new der;
    // таким образом, любители трястись наl невиртуальным диструктором могут спать спокойно
    
    
    der d;
    
    // поскольку der не является vector, то приведение не допустимо:
    // error: ‘vector’ is an inaccessible base of ‘der’
    // foo(d);
    
    // error: ‘void vector::reserve(size_t)’ is inaccessible
    // мы не разрешали этот функционал
    //d.reserve(10);
    
    
    d.size(); //<--- этот функционал мы разрешили
}
Но опять таки,
на практике основной юзкейс переиспользования контейнеров - породить своего наследника,
и работать только с этим наследником.

Никто не трогает ни базовый класс, ни полиморфизм.
Поэтому, имхо смысла в защищенном наследовании не много.

Проще сделать открытое наследование и не заморачиваться.
0
What a waste!
 Аватар для gray_fox
1610 / 1302 / 180
Регистрация: 21.04.2012
Сообщений: 2,733
02.02.2015, 22:47
Цитата Сообщение от hoggy Посмотреть сообщение
Поэтому, имхо смысла в защищенном наследовании не много.
Ну, как бы это правильно сказать... это "более правильное" решение, т.к. в вашем случае открытое наследование есть не то отношение, которое хочет использовать тот, кто проектирует, он его использует лишь только по тому, что "писать меньше".
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
02.02.2015, 22:53
Цитата Сообщение от gray_fox Посмотреть сообщение
Ну, как бы это правильно сказать... это "более правильное" решение, т.к. в вашем случае открытое наследование есть не то отношение, которое хочет использовать тот, кто проектирует, он его использует лишь только по тому, что "писать меньше".
"Более правильные" решения - те, которые просты, и не создают проблем.
"правильность" ради "правильности" - не нужна.

Там, где есть реальная необходимость - конечно, на то она и необходимость.

Но в большинстве случаев наследования от std::контейнеров, наследник не привносит собственных полей.
Никто не использует никакого полиморфизма.

В общем это все безопасно на практике. Потому и нет смысла заморачиваться.


Но открытое, или защищенное - наследование в любом случае лучше, когда нужно поиметь функционал,
чем композиция, потому что проще, и кода меньше.

Для того что бы делать именно композицию нужны причины поболее, чем:
"о боже! Нельзя наследоваться от стандартных контейнеров! Это ведь такой ужассно плохой тон. Об этом ведь во всех книжках писали для новичков".
0
What a waste!
 Аватар для gray_fox
1610 / 1302 / 180
Регистрация: 21.04.2012
Сообщений: 2,733
02.02.2015, 23:02
Цитата Сообщение от hoggy Посмотреть сообщение
В общем это все безопасно на практике. Потому и нет смысла заморачиваться.
Ну... возможно, но я бы не стал так реализовывать адаптер (и советовать не буду )
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
02.02.2015, 23:04
Цитата Сообщение от gray_fox Посмотреть сообщение
Ну... возможно, но я бы не стал так реализовывать адаптер (и советовать не буду )
Смысли, вообще через наследование? Или только через открытое?
0
What a waste!
 Аватар для gray_fox
1610 / 1302 / 180
Регистрация: 21.04.2012
Сообщений: 2,733
02.02.2015, 23:07
Цитата Сообщение от hoggy Посмотреть сообщение
"о боже! Нельзя наследоваться от стандартных контейнеров! Это ведь такой ужассно плохой тон. Об этом ведь во всех книжках писали для новичков".
Дело ведь не в том, что "Это ведь такой ужассно плохой тон", просто публичное наследование - это не то отношение классов, которое по сути нужно, т.е. это "хак" что бы "меньше буковок писать, все и так всё знают")

Добавлено через 21 секунду
Цитата Сообщение от hoggy Посмотреть сообщение
Смысли, вообще через наследование? Или только через открытое?
Через открытое.
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
02.02.2015, 23:13
Цитата Сообщение от gray_fox Посмотреть сообщение
Дело ведь не в том, что "Это ведь такой ужассно плохой тон", просто публичное наследование - это не то отношение классов, которое по сути нужно, т.е. это "хак" что бы "меньше буковок писать, все и так всё знают")
Не, не, погодите.
Я повторюсь: основной юзкейс такого наследования таков,
что наследник никаких своих полей не привносит.

И вот что бы далеко не ходить, из этой же темы:

Цитата Сообщение от Renji Посмотреть сообщение
Интерфейс от std::map плюс свой конструктор наполняющий мап из файла. Наследование потому что так писанины меньше.
При публичном наследовании, наследник действительно реализует отношение "являюсь".

наследник господина Renji не перестал быть std::map при публичном наследовании.
И может быть безопасно использован везде, где используется std::map.
-------------------------------------------

Вот при защищенном наследовании - там да, там уже отношение иное.
Но на то оно и защищенное.

Защищенное наследование для того и делают защищенным, что бы явно подчеркнуть:
"я не являюсь им, я лишь умею все, что умеет он".

Так что отношения между классами вполне соответствуют задумке разработчика.
0
What a waste!
 Аватар для gray_fox
1610 / 1302 / 180
Регистрация: 21.04.2012
Сообщений: 2,733
02.02.2015, 23:17
Цитата Сообщение от hoggy Посмотреть сообщение
При публичном наследовании, наследник действительно реализует отношение "являюсь".
Которое адаптеру не нужно.
Цитата Сообщение от hoggy Посмотреть сообщение
Вот при защищенном наследовании - там да, там уже отношение иное.
Но на то оно и защищенное.
Защищенное наследование для того и делают защищенным, что бы явно подчеркнуть:
"я не являюсь им, я лишь умею все, что умеет он".
Ну так я про это и писал (вроде ) - protected/private наследование - 'implemented by", а не "is a". Но при открытом то наследовании писанины то всё равно меньше)
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
02.02.2015, 23:26
Цитата Сообщение от gray_fox Посмотреть сообщение
Которое адаптеру не нужно.
А это зависит от конкретной ситуации с конкретным адаптером.

Он может ничего принципиально не изменяя,
лишь добавить в интерфейс ещё какой нибудь метод, например.

Цитата Сообщение от gray_fox Посмотреть сообщение
Но при открытом то наследовании писанины то всё равно меньше)
Ага.

Поэтому, в отдельных ситуациях есть смысл подумать о последствиях, а потом забить на правила,
и делать как проще и удобнее.
0
What a waste!
 Аватар для gray_fox
1610 / 1302 / 180
Регистрация: 21.04.2012
Сообщений: 2,733
02.02.2015, 23:29
Цитата Сообщение от hoggy Посмотреть сообщение
Он может ничего принципиально не изменяя,
лишь добавить в интерфейс ещё какой нибудь метод, например.
Ну мб, но КМК это обычно как раз ограничение\адаптация функционала (как в адаптерах STL).
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
02.02.2015, 23:32
Цитата Сообщение от gray_fox Посмотреть сообщение
КМК
что это?
0
02.02.2015, 23:33

Не по теме:

Цитата Сообщение от hoggy Посмотреть сообщение
что это?
как мне кажется, сорри( :) )

0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
02.02.2015, 23:36
Цитата Сообщение от gray_fox Посмотреть сообщение
но КМК это обычно как раз ограничение\адаптация функционала
Ну да. И что примечательно: адаптеры для того и нужны,
что бы вызывающая сторона работала именно с адаптером,
а не с тем зоопарком, который он адаптирует.

Поэтому, в плане использования, вызывающую сторону совершенно не парит:
от чего он там унаследовался, или чего он там агрегировал.
0
What a waste!
 Аватар для gray_fox
1610 / 1302 / 180
Регистрация: 21.04.2012
Сообщений: 2,733
02.02.2015, 23:44
Цитата Сообщение от hoggy Посмотреть сообщение
Поэтому, в плане использования, вызывающую сторону совершенно не парит:
от чего он там унаследовался, или чего он там агрегировал.
Ну, как я уже писал, может быть, ведь все более-менее опытные пользователи "плюсов" и так в курсе об этой "практике", но это не отменяет того факта, что публичное наследование здесь не к месту и лишь экономит "кнопконажатия" и ничего более.
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
02.02.2015, 23:53
Цитата Сообщение от gray_fox Посмотреть сообщение
что публичное наследование здесь не к месту и лишь экономит "кнопконажатия" и ничего более.
То есть техника,
которая позволяет получить профит быстрее и проще - это вы называете "не к месту"?

Даже несмотря на то, что в тех случаях, когда так делают,
наследник правомерно сохраняет отношение "является",
просто потому, что может быть использован везде, где может использован базовый класс?

Тем не менее, по вашему это все равно нарушает некую каноничную оо-религию?

Лично я вертел все эти религии, если следование их канонам ничего не укрощает и не облегчает,
а только создает проблемы.

Поэтому, предлагаю не развивать диалог в религиозном русле.
Только практика, только реальный профит.
0
What a waste!
 Аватар для gray_fox
1610 / 1302 / 180
Регистрация: 21.04.2012
Сообщений: 2,733
03.02.2015, 00:03
Цитата Сообщение от hoggy Посмотреть сообщение
Лично я вертел все эти религии, если следование их канонам ничего не укрощает и не облегчает
Я в принципе против "религий", но на моей памяти это одна и зтих вещей, которые меня действительно сбивали при просмотре либ вроде stl\boost (пока "не допёр"). К сожалению, в С++ нет "public implemented by", да.

Добавлено через 2 минуты
Цитата Сообщение от hoggy Посмотреть сообщение
Поэтому, предлагаю не развивать диалог в религиозном русле.
Ну да, это в первую очередь "идеологически" с т.з. ООП совершенно не верно (не то, что бы я прямо огромный фанат ООП ) использовать для этого public inheritance.
0
 Аватар для DiffEreD
1458 / 795 / 257
Регистрация: 21.06.2011
Сообщений: 1,740
Записей в блоге: 2
03.02.2015, 00:06
Как то однажды мне захотелось определить свой тип данных, строку с функционалом std:string и переопределить в нем лиши оператор ввода. Выбрал наследование. Так действительно вроде проще. И весь функционал std::string сберегся. Вот такой код был:
Кликните здесь для просмотра всего текста
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
template <typename CharT,
          typename Traits = std::char_traits<CharT>,
          typename Allocator = std::allocator<CharT>>
class string_no_punct : public std::basic_string<CharT, Traits, Allocator>
{
   using basic_str = std::basic_string<CharT, Traits, Allocator>;
public:
   using basic_str::basic_str;
   using basic_str::operator =;
 
   friend
   std::basic_istream<CharT, Traits>&
   operator>>(std::basic_istream<CharT, Traits>& is,
              string_no_punct<CharT, Traits, Allocator>& str)
   {
      basic_str temp;
      is >> temp;
      auto pos = std::find_if(temp.begin(), temp.end(), ::ispunct);
      temp.erase(pos, temp.end());
      str = std::move(temp);
      return is;
   }
};
 
using mystring = string_no_punct<char>;
 
int main()
{
   std::istringstream iss{"one, two,, three; four: five"};
   std::vector<mystring> v{std::istream_iterator<mystring>(iss),
                           std::istream_iterator<mystring>()};
   for (auto s : v) std::cout << s << " ";
   std::cout << "\n\n-----------------------\n\n";
 
   mystring ms;
   std::cout << "Enter str whith punct: ->";
   std::cin >> ms;
   std::cout << ms << "\n";
}
0
419 / 418 / 72
Регистрация: 27.05.2012
Сообщений: 1,168
03.02.2015, 08:38
Цитата Сообщение от hoggy Посмотреть сообщение
Ага. Но в этом случае все равно в разы меньше, чем при композиции.
да при закрытом наследовании кода будет ровным счетом столько же, сколько при композиции
да, при реализации типа данных не сильно отличного от имеющегося, к примеру реализуем авто сортируемый вектор из вектора, то ту наследование позволяет сберечь нервы и время, при реализации адаптеров вроде стэк и очередь выгоды от наследования перед композицией не будет никакой - они равнозначны в данном случае!
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
03.02.2015, 08:38
Помогаю со студенческими работами здесь

Шифрование "Лозунговым методом" (кому интересно)
Вот работа была сделал -&gt; делюсь:) #include &lt;stdio.h&gt; #include &lt;conio.h&gt; #include &lt;string.h&gt; #include...

В чем интересно загвоздка???интересно разобраться!
Помогите разобраться в чем дело? Switch постоянно зацикливается и бесконечный цикл получается если вводить символы вместо цифр как от этого...

Уважаемые! Хотите немного поломать голову!?
Вообщем сижу, туплю... а бошка совсем не варит, всю ночь не спал(думаю всем знакомо это очучение) а тут на тебе задачку дали... Вообщем...

Задача для любителей поломать голову
Вот наткнулся на задачу Расшифруйте! Подсказка- 2 шага http://s3.uploads.ru/QGrIM.png

Открыта вакансия Программиста 1С - кому интересно?
Добрый день! Меня зовут Анна и я являюсь представителем кадровой компании, работаю как официальный представитель многих компаний города...


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

Или воспользуйтесь поиском по форуму:
60
Закрытая тема Создать тему
Новые блоги и статьи
Access
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
Фото: Daniel Greenwood
kumehtar 13.11.2025
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru