С Новым годом! Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.56/25: Рейтинг темы: голосов - 25, средняя оценка - 4.56
1458 / 795 / 257
Регистрация: 21.06.2011
Сообщений: 1,740
Записей в блоге: 2
1

shared_ptr и реализация семантики переноса

25.12.2012, 16:21. Показов 5055. Ответов 21
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Написал небольшой класс Array основанный на std::shared_ptr. Но как то не совсем уверен в правильности реализации конструктора и оператора переноса. Плюс, возникли какие то неполадки с перегруженным оператором + - он почему то модифицирует объекты которых не должен модифицировать. Что в моем коде не правильно?
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
#include <iostream>
#include <algorithm>
#include <iterator>
#include <memory>
#include <functional>
 
template<typename T>
class Array
{
    std::shared_ptr<T> m_array;
    size_t m_size;
public:
    typedef T*          iterator;
    typedef const T*    const_iterator;
    iterator        begin()         {return m_array.get();}
    iterator        end()           {return m_array.get()+m_size;}
    const_iterator  begin() const   {return m_array.get();}
    const_iterator  end()   const   {return m_array.get()+m_size;}
 
    const T operator[](size_t index) const {return *(m_array.get()+index);}
    T operator[](size_t index) {return *(m_array.get()+index);}
 
    explicit Array(size_t size = 0, const T& value = T()) : m_size(size),
        m_array(new T[size], std::default_delete<T[]>())
    {
        std::fill(m_array.get(), m_array.get()+m_size, value);
    }
 
    Array(const Array& obj) : m_size(obj.m_size), m_array(obj.m_array) {std::cout<<"Array(const Array& obj)\n";}
 
    Array(Array&& obj) : m_size(std::move(obj.m_size)), m_array(std::move(obj.m_array))
    {
        std::cout<<"Array(Array&& obj)\n";
        obj.m_size = 0;
        obj.m_array.reset();
    }
 
    Array& operator=(const Array& obj)
    {
        std::cout<<"Array& operator=(const Array& obj)\n";
        if (this == &obj)
            return *this;
        m_size = obj.m_size;
        m_array = obj.m_array;
        return *this;
    }
 
    Array& operator=(Array&& obj)
    {
        std::cout<<"Array& operator=(Array&& obj)\n";
        m_size = std::move(obj.m_size);
        m_array = std::move(obj.m_array);
        obj.m_size = 0;
        obj.m_array.reset();
        return *this;
    }
 
    Array& operator+=(const Array& rhs)
    {
        std::transform(begin(), end(), rhs.begin(), begin(), std::plus<T>());
        return *this;
    }
 
    Array operator+(const Array& rhs)
    {
        Array ar;
        ar = *this;
        ar+=rhs;
        return ar;
    }
};
 
int main()
{
    {
        Array<int> a1(10, 6);
        Array<int> a2(a1);       //копирующий конструктор
 
 
        /*std::copy(a1.begin(), a1.end(), std::ostream_iterator<int>(std::cout," "));
        std::cout<<"\n\n";
        std::copy(a2.begin(), a2.end(), std::ostream_iterator<int>(std::cout," "));
        std::cout<<"\n\n";
        std::copy(a1.begin(), a1.end(), std::ostream_iterator<int>(std::cout," "));*/
 
        Array<int> b1(a2);      //копирующий конструктор
        Array<int> b2;
        b2 = a1+a2;            //почему то модифицирует объекты a1, a2 и b1
 
        std::cout<<"\n\n";
        std::copy(b1.begin(), b1.end(), std::ostream_iterator<int>(std::cout," "));
 
        std::cout<<"\n\n";
        std::copy(b2.begin(), b2.end(), std::ostream_iterator<int>(std::cout," "));
 
        std::cout<<"\n\n";
        std::copy(a1.begin(), a1.end(), std::ostream_iterator<int>(std::cout," "));
        std::cout<<"\n\n";
        std::copy(a2.begin(), a2.end(), std::ostream_iterator<int>(std::cout," "));
 
    }
    std::cout<<"\n\n";
    system("pause");
    return 0;
}
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
25.12.2012, 16:21
Ответы с готовыми решениями:

Реализация shared_ptr
Добрый день. Реализовал shared_ptr(), но если больше 2 перемен он не правильно работает. Что я ...

Shared_ptr собственная реализация
Здравствуйте, написал собственную реалицацию &quot;умных&quot; указателей для класса object. Прежде чем...

Реализация переноса
Всем привет! Тут такая задачка. Надо нарисовать параллелепипед, и чтобы при нажатии например кнопки...

Реализация переноса данных из таблицы Excel в checkedListBox
Здравствуйте! Подскажите, пожалуйста, как реализовать перенос значений ячеек из книги Excel в...

21
В астрале
Эксперт С++
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
25.12.2012, 16:33 2
yuron_477,
C++
1
obj.m_array.reset();
зачем? shared_ptr сам умный, сам это сделает. int перемещать вцелом резона нет, ибо он в любом случае скопируется.)
1
What a waste!
1610 / 1302 / 180
Регистрация: 21.04.2012
Сообщений: 2,733
25.12.2012, 16:36 3
Цитата Сообщение от yuron_477 Посмотреть сообщение
std::move(obj.m_size)
Это ни к чему, пожалуй (std::move).
Цитата Сообщение от yuron_477 Посмотреть сообщение
//почему то модифицирует объекты a1, a2 и b1
Ну так эти объекты ссылаются на один и тот же участок памяти, у тебя же shared_ptr внутри, и ты при конструировании копируешь их, а не то, на что они ссылаются.
1
1458 / 795 / 257
Регистрация: 21.06.2011
Сообщений: 1,740
Записей в блоге: 2
25.12.2012, 16:48  [ТС] 4
Ну а как сделать чтобы все логически правильно работало, а то что то я никак не соображу?
0
What a waste!
1610 / 1302 / 180
Регистрация: 21.04.2012
Сообщений: 2,733
25.12.2012, 16:58 5
Я бы хранил unique_ptr, в copy c-tor - std::copy, в move c-tor - std::move.

Добавлено через 6 минут
Или можно сделать класс неизменяемым, т.е. никаких операторов с присвоением.
1
В астрале
Эксперт С++
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
25.12.2012, 17:37 6
А я бы как-то так сделал. CoW собственно. Не очень хорошо по отношению к безопасности исключений да и copy-swap бы сделать, но лень.

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
#include <iostream>
#include <algorithm>
#include <iterator>
#include <memory>
#include <functional>
 
template<typename T>
class Array
{
    std::shared_ptr<T> m_array;
    size_t m_size;
public:
    typedef T*          iterator;
    typedef const T*    const_iterator;
    iterator        begin()         {return m_array.get();}
    iterator        end()           {return m_array.get()+m_size;}
    const_iterator  begin() const   {return m_array.get();}
    const_iterator  end()   const   {return m_array.get()+m_size;}
 
    const T operator[](size_t index) const {return *(m_array.get()+index);}
    T operator[](size_t index) {return *(m_array.get()+index);}
 
    explicit Array(size_t size = 0, const T& value = T()) : m_size(size),
        m_array(new T[size], std::default_delete<T[]>())
    {
        std::fill(m_array.get(), m_array.get()+m_size, value);
    }
 
    Array(const Array& obj) : m_size(obj.m_size), m_array(obj.m_array) {std::cout<<"Array(const Array& obj)\n";}
 
    Array(Array&& obj) : m_size(obj.m_size), m_array(std::move(obj.m_array))
    {
        std::cout<<"Array(Array&& obj)\n";
        obj.m_size = 0;
    }
 
    Array& operator=(const Array& obj)
    {
        std::cout<<"Array& operator=(const Array& obj)\n";
        if (this == &obj)
            return *this;
        m_size = obj.m_size;
        m_array = obj.m_array;
        return *this;
    }
 
    Array& operator=(Array&& obj)
    {
        std::cout<<"Array& operator=(Array&& obj)\n";
        m_size = obj.m_size;
        m_array = std::move(obj.m_array);
        obj.m_size = 0;
        return *this;
    }
 
    Array& operator+=(const Array& rhs)
    {
        std::transform(begin(), end(), rhs.begin(), begin(), std::plus<T>());
        return *this;
    }
 
    Array operator+(const Array& rhs)
    {
        Array ar = deep_copy();
        ar+=rhs;
        return ar;
    }
private:
    Array deep_copy()
    {
       Array ar;
       ar.m_array = std::shared_ptr<T>(new T[m_size], std::default_delete<T[]>());
       const T* array = m_array.get();
       std::copy(array, array + m_size, ar.m_array.get());
       ar.m_size = m_size;
       return ar;
    }
};
 
int main()
{
    {
        Array<int> a1(10, 6);
        Array<int> a2(a1);       //копирующий конструктор
 
 
        /*std::copy(a1.begin(), a1.end(), std::ostream_iterator<int>(std::cout," "));
        std::cout<<"\n\n";
        std::copy(a2.begin(), a2.end(), std::ostream_iterator<int>(std::cout," "));
        std::cout<<"\n\n";
        std::copy(a1.begin(), a1.end(), std::ostream_iterator<int>(std::cout," "));*/
 
        Array<int> b1(a2);      //копирующий конструктор
        Array<int> b2;
        b2 = a1+a2;            //почему то модифицирует объекты a1, a2 и b1
 
        std::cout<<"\n\n";
        std::copy(b1.begin(), b1.end(), std::ostream_iterator<int>(std::cout," "));
 
        std::cout<<"\n\n";
        std::copy(b2.begin(), b2.end(), std::ostream_iterator<int>(std::cout," "));
 
        std::cout<<"\n\n";
        std::copy(a1.begin(), a1.end(), std::ostream_iterator<int>(std::cout," "));
        std::cout<<"\n\n";
        std::copy(a2.begin(), a2.end(), std::ostream_iterator<int>(std::cout," "));
 
    }
    std::cout<<"\n\n";
    return 0;
}
Добавлено через 16 минут
copy/move_and_swap можно сделать как-нибудь так к примеру. Ну это так, изврата ради.

C++
1
2
3
4
5
6
7
8
    template<typename Internal>
    void internal_swap(Internal&& rhs)
    {
       std::swap(m_size, rhs.m_size);
       std::shared_ptr<T> array = m_array;
       m_array = std::forward<std::shared_ptr<T>>(rhs.m_array);
       rhs.m_array = array;
    }
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
    Array& operator=(const Array& obj)
    {
        std::cout<<"Array& operator=(const Array& obj)\n";
        if (this == &obj)
            return *this;
        Array ar(obj);
        internal_swap(ar);
        return *this;
    }
 
    Array& operator=(Array&& obj)
    {
        std::cout<<"Array& operator=(Array&& obj)\n";
        internal_swap(std::forward<Array>(obj));
        obj.m_size = 0;
        return *this;
    }
2
What a waste!
1610 / 1302 / 180
Регистрация: 21.04.2012
Сообщений: 2,733
25.12.2012, 18:21 7
Как вариант, не особо красиво конечно)
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
#include <iostream>
#include <memory>
#include <utility>
#include <algorithm>
#include <iterator>
#include <type_traits>
#include <initializer_list>
 
 
template<typename T>
class array {
   
public:
   typedef array           self_type;
   typedef T               value_type;
   typedef T *             pointer;
   typedef T const*        const_pointer;
   typedef T &             reference;
   typedef T const&        const_reference;
   typedef std::size_t     size_type;
   typedef std::ptrdiff_t  difference_type;
   typedef const_pointer   iterator;
   typedef const_pointer   const_iterator;
   
   
   const_iterator begin() const {
      return arrayPtr.get();
   }
   
   const_iterator end() const {
      return arrayPtr.get() + arraySize;
   }
   
   
   const_reference operator [](size_type const idx) const {
      return arrayPtr[idx];
   }
   
   
   size_type size() const {
      return arraySize;
   }
   
   
   void swap(self_type & other) {
      std::swap(arrayPtr,  other.arrayPtr);
      std::swap(arraySize, other.ArraySize);
   }
   
   
   explicit array(size_type const s = 0, const_reference v = T())
         : arrayPtr(new T[s], std::default_delete<T[]>())
         , arraySize(s) {
      std::fill(&*arrayPtr, &*arrayPtr + arraySize, v);      
   }
         
   template<typename Iterator>
   array(Iterator const first, Iterator const last)
         : arraySize(std::distance(first, last)) {
      arrayPtr.reset(new T[arraySize], std::default_delete<T[]>());
      std::copy(first, last, &*arrayPtr);
   }
   
   template<
         typename S
       , typename = typename std::enable_if<std::is_convertible<S, T>::value>::type
   >
   array(std::initializer_list<S> list)
         : array(std::begin(list), std::end(list)) {}
   
   array(self_type const& other)
         : arrayPtr(other.arrayPtr)
         , arraySize(other.arraySize) {}
   
   template<
         typename S
       , typename = typename std::enable_if<std::is_convertible<S, T>::value>::type
   >
   array(array<S> const& other)
         : array(other.begin(), other.end()) {}
      
   array(self_type && other)
         : arrayPtr(std::move(other.arrayPtr))
         , arraySize(other.arraySize) {}
           
   
   array & operator =(array const&) = delete;
   array & operator =(array &&)     = delete;
            
  
private:
   template<typename S>
   friend class array;
   
   template<typename S, typename L>
   array<typename std::common_type<S, L>::type>
   friend operator +(array<S> const& lhs, array<L> const& rhs);
   
 
   std::shared_ptr<T>   arrayPtr;
   size_type            arraySize;
};
 
 
template<typename T, typename S>
array<typename std::common_type<T, S>::type>
operator +(array<T> const& lhs, array<S> const& rhs) {
   using result_type = typename std::common_type<T, S>::type;
   
   array<result_type> result(std::max(lhs.size(), rhs.size()));
   
   if (lhs.size() < rhs.size()) {
      std::copy(rhs.begin(), rhs.end(), &*result.arrayPtr);
      std::transform(lhs.begin(), lhs.end(), rhs.begin(), &*result.arrayPtr, std::plus<result_type>());
   } else {
      std::copy(lhs.begin(), lhs.end(), &*result.arrayPtr);
      std::transform(rhs.begin(), rhs.end(), lhs.begin(), &*result.arrayPtr, std::plus<result_type>());
   }
   
   return result;
}
 
 
int main() {
   array<int>     a1 = {1, 2, 3, 4, 5};
   array<double>  a2 = {1.23, 432., 5.66, 5.56};
   array<int>     b1(a1);
   array<double>  b2(a2);
   array<float>   b3(a1);
   
   auto r1 = a1 + b1;
   std::copy(std::begin(r1), std::end(r1), std::ostream_iterator<int>(std::cout, " "));
   std::cout << std::endl;
   
   auto r2 = a1 + a2;
   std::copy(std::begin(r2), std::end(r2), std::ostream_iterator<double>(std::cout, " "));
   std::cout << std::endl;
   
   auto r3 = b1 + b2 + b3;
   std::copy(std::begin(r3), std::end(r3), std::ostream_iterator<double>(std::cout, " "));
   std::cout << std::endl;
   
   auto r4 = std::move(r3);
   std::copy(std::begin(r4), std::end(r4), std::ostream_iterator<double>(std::cout, " "));
   std::cout << std::endl;
}
4
Эксперт С++
8483 / 6150 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
28.12.2012, 15:24 8
Стоит отметить, что рассмотренные мною умные указатели (кроме unique_ptr) не предназначен для владения массивами. Это связано с тем, что деструктор вызывает именно delete, а не delete[] (что требуется для массивов).
http://www.kalnitsky.org/2011/... -in-cpp11/
0
1458 / 795 / 257
Регистрация: 21.06.2011
Сообщений: 1,740
Записей в блоге: 2
28.12.2012, 15:29  [ТС] 9
Ну так default_delete для чего придумали: http://en.cppreference.com/w/c... ult_delete
1
Эксперт С++
8483 / 6150 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
28.12.2012, 15:55 10
20.7.1.1.1 In general [unique.ptr.dltr.general]
1 The class template default_delete serves as the default deleter (destruction policy) for the class template
unique_ptr.
2 The template parameter T of default_delete may be an incomplete type.
Разве это не только для std::unique_ptr ?

Добавлено через 10 минут
Все понял... не не только для std::unique_ptr
0
279 / 39 / 13
Регистрация: 11.10.2015
Сообщений: 405
26.02.2017, 23:42 11
gray_fox, вот так ,думаю, будет надежнее
C++
1
std::fill(std::addressof(*arrayPtr), std::addressof(*arrayPtr) + arraySize, v);
1
279 / 39 / 13
Регистрация: 11.10.2015
Сообщений: 405
09.04.2017, 11:41 12
gray_fox, да, и заместо медленного new лучше std::make_shared использовать, т.к он быстрее и надежнее
0
Любитель чаепитий
3744 / 1800 / 566
Регистрация: 24.08.2014
Сообщений: 6,016
Записей в блоге: 1
09.04.2017, 12:41 13
Цитата Сообщение от zarko97 Посмотреть сообщение
т.к он быстрее
откуда информация?
0
279 / 39 / 13
Регистрация: 11.10.2015
Сообщений: 405
09.04.2017, 13:14 14
GbaLog-, в этой ситуации new выполняет выделение памяти дважды: для объекта и управляющего им блока, а std::make_shared выполняет одно выделение и значительно надежнее и безопаснее, если аллокация памяти завершится неудачей
1
Любитель чаепитий
3744 / 1800 / 566
Регистрация: 24.08.2014
Сообщений: 6,016
Записей в блоге: 1
09.04.2017, 13:33 15
Цитата Сообщение от zarko97 Посмотреть сообщение
значительно надежнее и безопаснее, если аллокация памяти завершится неудачей
если аллокация завершится неудачей, то в любом случае std::bad_alloc вылетит.
0
279 / 39 / 13
Регистрация: 11.10.2015
Сообщений: 405
09.04.2017, 13:37 16
GbaLog-, да...но в 1 случае деструктор у std::shared_ptr не вызовется, сам знаешь чем это чревато
0
Любитель чаепитий
3744 / 1800 / 566
Регистрация: 24.08.2014
Сообщений: 6,016
Записей в блоге: 1
09.04.2017, 13:44 17
Цитата Сообщение от zarko97 Посмотреть сообщение
да...но в 1 случае деструктор у std::shared_ptr не вызовется, сам знаешь чем это чревато
ну и что? программа упадёт от бэд аллока, или ты его перехватывать собрался?
0
279 / 39 / 13
Регистрация: 11.10.2015
Сообщений: 405
09.04.2017, 14:13 18
GbaLog-, я тут немного другое имел ввиду: о ситуации выделения памяти для управляющего блока

Добавлено через 1 минуту
GbaLog-, https://www.youtube.com/watch?... iM&t=3466s

Добавлено через 1 минуту
GbaLog-, смотри с 31:40
0
Любитель чаепитий
3744 / 1800 / 566
Регистрация: 24.08.2014
Сообщений: 6,016
Записей в блоге: 1
09.04.2017, 16:08 19
Цитата Сообщение от zarko97 Посмотреть сообщение
смотри с 31:40
посмотрел, но так и не понял, что ты имел ввиду.
я понял, что при std::make_shared происходит 1 вызов менеджера памяти, при new происходит 2 вызова.
за это я тебя поблагодарил, но про безопасность из доклада только понял, что не стоит использовать new явно.
почему - не понял, в любом случае счетчик ссылок сделает всё за нас.
0
279 / 39 / 13
Регистрация: 11.10.2015
Сообщений: 405
09.04.2017, 16:47 20
GbaLog-, вроде у Майерса есть неплохая инфа ст. 147-149

Добавлено через 22 секунды
GbaLog-, Effective Modern C++
1
09.04.2017, 16:47
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
09.04.2017, 16:47
Помогаю со студенческими работами здесь

Реализация переноса данных из таблицы Excel в checkedListBox
Здравствуйте! Подскажите, пожалуйста, как реализовать перенос значений ячеек из листа Excel(.xlsx)...

Технология программирования. Методы спецификации семантики функций
Здравствуйте! Помогите пожалуйста. Задание: Тип R определён с помощью следующей аксиоматической...

Где найти список всех операторов С++ с описанием их семантики?
Хочу обучить некоторый проект искусственного разума составлять программы на С++ по установленным...

Нюансы синтаксиса и семантики: что такое rvalue и lvalue?
Добрый день, всем. Ребят, помогите разобраться в rvalue и lvalue. Читал об этом много чего, но все...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Это работает. Скорость асинхронной логики велика. Вопрос видимо останется в стабильности. Плата - огонь!
Hrethgir 13.01.2025
По прошлому проекту в Logisim Evolution https:/ / www. cyberforum. ru/ blogs/ 223907/ blog8781. html прилагаю файл архива проекта Gowin Eda и снимок. Восьмибитный счётчик из сумматора+ генератор сигнала. . .
UserScript для подсветки кнопок языков программировани­­­­я в зависимости от текущего раздела
volvo 13.01.2025
В результате работы этого скрипта подсвечиваются нужные кнопки не только в форме быстрого ответа, но и при редактировании сообщения: / / ==UserScript== / / @name CF_DefaultLangSelect / / . . .
Введение в модели и алгоритмы машинного обучения
InfoMaster 12.01.2025
Машинное обучение представляет собой одну из наиболее динамично развивающихся областей искусственного интеллекта, которая фокусируется на разработке алгоритмов и методов, позволяющих компьютерам. . .
Как на Python создать нейросеть для решения задач
InfoMaster 12.01.2025
В контексте стремительного развития современных технологий особое внимание уделяется таким инструментам, как нейросети. Эти структуры, вдохновленные биологическими нейронными сетями, используются для. . .
Как создать нейросеть для генерации картинок на Python
InfoMaster 12.01.2025
Генерация изображений с помощью искусственных нейронных сетей стала одним из наиболее захватывающих направлений в области компьютерного зрения и машинного обучения. В этой статье мы рассмотрим. . .
Создание нейросети для генерации текста на Python
InfoMaster 12.01.2025
Нейросети, или искусственные нейронные сети, представляют собой модели машинного обучения, вдохновленные работой человеческого мозга. Они состоят из множества взаимосвязанных узлов, или "нейронов",. . .
Как создать нейросеть распознавания изображений на Python
InfoMaster 12.01.2025
Введение в распознавание изображений с помощью нейросетей Распознавание изображений с помощью нейронных сетей стало одним из самых впечатляющих достижений в области искусственного интеллекта. Эта. . .
Основы искуственного интеллекта
InfoMaster 12.01.2025
Искусственный интеллект (ИИ) представляет собой одну из наиболее динамично развивающихся областей современной науки и технологий. В широком смысле под искусственным интеллектом понимается способность. . .
Python и нейросети
InfoMaster 12.01.2025
Искусственные нейронные сети стали неотъемлемой частью современных технологий, революционизировав множество областей - от медицинской диагностики до автономных транспортных средств. Python, благодаря. . .
Python в машинном обучении
InfoMaster 12.01.2025
Python стал неотъемлемой частью современного машинного обучения, завоевав позицию ведущего языка программирования в этой области. Его популярность обусловлена несколькими ключевыми факторами, которые. . .
Создание UI на Python с TKinter
InfoMaster 12.01.2025
TKinter — это одна из наиболее популярных библиотек для создания графических интерфейсов пользователей (GUI) в языке программирования Python. TKinter входит в стандартную библиотеку Python, что. . .
HTML5 в разработке мобильных приложений
InfoMaster 12.01.2025
Введение: Обзор роли HTML5 в мобильной разработке В современном мире мобильных технологий HTML5 стал ключевым инструментом для разработки кроссплатформенных приложений. Эта технология произвела. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru