Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.96/67: Рейтинг темы: голосов - 67, средняя оценка - 4.96
Заблокирован

Неочевидные грабли полиморфизма с++

23.11.2011, 01:05. Показов 16476. Ответов 101
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Наткнулся в интернете на любопытный код.
Спешу поделиться с сообществом.
Просто, что бы кто если не в курсе - узнал, и не попал на эти грабли:


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
#include <iostream>
using namespace std;
 
struct A
{
    virtual void Func1(){cout<<"A::Func1"<<endl;}
};
struct B
{ 
    virtual void Func2(){cout<<"B::Func2"<<endl;}}
;
struct C: public A, public B
{ 
    virtual void Func3(){cout<<"C::Func3"<<endl;}
};
 
int main()
{
    A *ptr = new C;
    void *ptr1 = new C;
    
    ((A*)ptr)->Func1(); //вывод: A::Func1
    ((B*)ptr)->Func2(); //вывод: A::Func1 Почему?
    ((C*)ptr)->Func3(); //вывод: C::Func3
    
    A* aPtr=dynamic_cast<A*>(ptr);
    B* bPtr=dynamic_cast<B*>(ptr);
    C* cPtr=dynamic_cast<C*>(ptr)
    
    //нельзя кастовать от void*
    //void* ничего не знает ни о каких классах
    //и ни о каких таблицах виртуальных функций
 
    C* cPtr=dynamic_cast<C*>(ptr1); //ошибка компиляции
    //error C2681: void *: недопустимый тип выражения для dynamic_cast
    
    aPtr->Func1(); //вывод: A::Func1
    bPtr->Func2(); //вывод: B::Func2
    cPtr->Func3(); //вывод: C::Func3
 
    delete ptr;
    delete ptr1;
 
    return 0;
}
От себя могу добавить, что разные компиляторы по разному могут реализовывать механизм полиморфизма. Поэтому, при множественном наследовании если что и спасет - только dynamic_cast
Но в любом случае, нужно быть предельно осторожным.

А по сути, полиморфизм + множественное наследование = мина замедленного действия.

Поэтому, при проектировании полиморфных классов, лучше до последнего избегать множественного наследования.
1
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
23.11.2011, 01:05
Ответы с готовыми решениями:

Неочевидные особенности выдачи pg таблиц
Я довольно много копаюсь в pg_* таблицах, дабы получать информацию о базе данных и прочих системных фишечках. Ближе к делу: ...

Неочевидные результаты очевидных css-свойств
Добрый вечер, господа верстальщики! Столкнулся с такой неочевидной для меня проблемой: Оказывается, добавив свойство padding:1px,...

Грабли с кодировкой
Здравствуйте! В конструкторе главного окна: MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new...

101
 Аватар для taras atavin
4226 / 1796 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
23.11.2011, 12:51
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от Bers Посмотреть сообщение
"указатель типа...", ну например: "указатель типа int"
Тип указателя это всегда тип указателя, а не самого данного. Например, указатель типа указателя на int. Или указатель типа int*. Но не просто типа int. Уж если типа int, то само число.
0
Эксперт С++
 Аватар для fasked
5045 / 2624 / 241
Регистрация: 07.10.2009
Сообщений: 4,310
Записей в блоге: 5
23.11.2011, 12:56
Цитата Сообщение от taras atavin Посмотреть сообщение
а не самого данного
Кто такой "данный"?
Цитата Сообщение от taras atavin Посмотреть сообщение
указатель типа указателя на int. Или указатель типа int*.
Мне в голову приходит сразу двойной указатель.
0
 Аватар для taras atavin
4226 / 1796 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
23.11.2011, 13:07
Цитата Сообщение от Bers Посмотреть сообщение
Вот вы и объясните почему?
Потому что не совместимы. Вот представь себе: домну превратить в корабль. Кто начал вспоминать заклятие? Отставить! Не мучайтесь, вы их не знаете. И это реальная Земля, а не вымысел про Сабрину. И так превращение домны в корабль. Сказано отставить магию! Лёгким движением руки домна превращается... Превращается домна... Домна преващается... в элегантные руины! Простите, это другой класс, нужен был корабль.

Добавлено через 1 минуту
Цитата Сообщение от ValeryLaptev Посмотреть сообщение
Нет тут перекрестного преобразования от базового к базовому.
А что тогда такое от A к B?

Добавлено через 7 минут
Цитата Сообщение от Deviaphan Посмотреть сообщение
Соответственно есть "два типа указателей" На объекты и на скаляры.
Во-первых один бит - ещё не конкретика, а во-вторых джавовики умудряются вообще отличать объекты от скаляров. Так что смысловой нагрузки в слове "объект" нет, если только не описывается синтаксис, или понятие.
0
Делаю внезапно и красиво
Эксперт С++
 Аватар для Deviaphan
1313 / 1228 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
23.11.2011, 13:08
Цитата Сообщение от taras atavin Посмотреть сообщение
указатель типа указателя на int. Или указатель типа int*. Но не просто типа int.
int** - указатель типа int*
int* - указатель типа int
int - просто тип инт

Слово "указатель" семантично равнозначно добавлению * к названию типа. Т.е. "тип int*" и "указатель на тип int" это одно и то же.
0
 Аватар для taras atavin
4226 / 1796 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
23.11.2011, 13:08
Цитата Сообщение от fasked Посмотреть сообщение
Кто такой "данный"?
данное, а не данный.
0
Делаю внезапно и красиво
Эксперт С++
 Аватар для Deviaphan
1313 / 1228 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
23.11.2011, 13:10
Цитата Сообщение от taras atavin Посмотреть сообщение
джавовики умудряются вообще отличать объекты от скаляров
А в С++ объект это область памяти. Скаляр тоже "область памяти". Для скаляров можно вызывать конструктор с параметрами. В ООП делается всё возможное, чтобы встроенные типы считались объектами.
0
 Аватар для taras atavin
4226 / 1796 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
23.11.2011, 13:18
Цитата Сообщение от Deviaphan Посмотреть сообщение
"тип int*" и "указатель на тип int" это одно и то же.
Вот именно. Но сам указатель типа int*, а не int.
C++
1
int *p;
Указатель здесь зовут p и это указатель на int. А теперь забыли слово "указатель". Какого типа p? В данном случае p типа int*. И никакого двойного! "p типа int*" - это
C++
1
int *p;
, различие в другом языке (русском вместо плюсов). А теперь вспоминаем, что p - это указатель. Так какого типа указатель? Конечно же типа double+! Нет? Неужели типа float/? Опять нет? Может типа char-?

Добавлено через 36 секунд
Цитата Сообщение от Deviaphan Посмотреть сообщение
джавовики умудряются вообще отличать объекты от скаляров
то есть не отличать.

Добавлено через 1 минуту
Цитата Сообщение от Deviaphan Посмотреть сообщение
Для скаляров можно вызывать конструктор с параметрами.
Ну ка вызови на плюсах. Попробуй также вызвать метод, или обратиться к полю.

Добавлено через 49 секунд
Цитата Сообщение от Deviaphan Посмотреть сообщение
В ООП делается всё возможное, чтобы встроенные типы считались объектами.
Делается, но плюсодевелоперами до конца не сделано.
0
Делаю внезапно и красиво
Эксперт С++
 Аватар для Deviaphan
1313 / 1228 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
23.11.2011, 13:25
Цитата Сообщение от taras atavin Посмотреть сообщение
Ну ка вызови на плюсах.
Вот, конструктор с параметром
C++
1
int a(123);
Про методы я ничего не говорил. Если проигнорировать вызов operator+ как метода, то можно сделать объект, внешне идентичный скаляру.

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

Добавлено через 28 секунд
Цитата Сообщение от Deviaphan Посмотреть сообщение
int a(123);
или
C++
1
double b = double(3.14);
0
Заблокирован
24.11.2011, 09:00  [ТС]
Цитата Сообщение от Deviaphan Посмотреть сообщение
Слово "указатель" семантично равнозначно добавлению * к названию типа. Т.е. "тип int*" и "указатель на тип int" это одно и то же.
Несколько раз перечитывал запись, пытаясь понять.
Всегда считал, что int* это и есть указатель

Сам по себе указатель - это и есть тип.

Другое дело, что переменная типа указатель содержит адрес объекта.
И эту переменную так же называют указателем.
C++
1
2
3
A* ptr = new C; //семантически, A* это объявление указателя типа A
                        //ptr - указатель типа A                        
                        //ptr - это указатель, который смотрит на объект типа C
В чем здесь подвох? Подвох в том, что "ptr указатель на A".
О том, что на самом деле он смотрит на объект типа C знают только программисты, да может быть всякие там динамик_касты.
Компилятор же считает, что указатель_на_тип априори указывает на объекты такого же типа.

Указатель_на_тип - нужно понимать, как тип самого указателя.

По сабжу, есть только два варианта:
1 Либо забить на производительность и юзать динамик_касты.
2 Либо программист сам отдаёт отчет в том, куда в каждый момент времени смотрят указатели, и какие там на самом деле живут объекты. И не допустить срезки.
Самый простой способ добиться такого эффекта - не юзать множественное наследование при полиморфизме. И вообще не делать глубоких/широких наследований. Тогда не придётся втыкать в низко-уровневую работу полиморфизма.
0
Делаю внезапно и красиво
Эксперт С++
 Аватар для Deviaphan
1313 / 1228 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
24.11.2011, 09:13
Цитата Сообщение от Bers Посмотреть сообщение
Несколько раз перечитывал запись, пытаясь понять.
Всегда считал, что int* это и есть указатель
Именно об этом я и написал, да.

Добавлено через 1 минуту
Вернее - нет.)
int* это тип, а переменная этого типа - указатель.

Добавлено через 2 минуты
Цитата Сообщение от Bers Посмотреть сообщение
1 Либо забить на производительность и юзать динамик_касты.
2 Либо программист сам отдаёт отчет в том, куда в каждый момент времени смотрят указатели, и какие там на самом деле живут объекты. И не допустить срезки.
1. Да
2. Нет. Программист не должен об этом думать. Если он должен об этом думать, скорее всего это ошибка проектирования.
Срезка бывает только при использовании значений. При использовании указателей и ссылок срезки не бывает.
0
Заблокирован
24.11.2011, 09:23  [ТС]
Цитата Сообщение от Deviaphan Посмотреть сообщение
Срезка бывает только при использовании значений.
Указатель на ЦЕ приводится к указателю на А не для того, что бы хранить указатель на А, и перед использованием привести его обратно к указателю на ЦЕ.

по сабжу, именно поэтому и происходила срезка - использовался указатель на А, ну или на Б, без учета того, на что действительно смотрел указатель.

А как это вообще получилось? У человека была самодельная фабрика, которая производила объекты типа ЦЕ, а наружу выдавала указатели на А.
И уже снаружи, вызывающая сторона приводила А к чему ей было нужно, ничего не зная о том, какой в действительности был сконструирован объект самой фабрикой.

На мой взгляд, человек допустил этот архитектурный ляп потому что не осознавал как работает полиморфизм на низком уровне. А когда осознал всю неправильность своего творчества, было уже поздно - слишком многое было завязано на такой фабрике. И ему не оставалось ничего иного, кроме как воспользоваться услугами динамик_каст.

Итого: неоправданное падение производительности там, где этого можно было с лёгкостью избежать.


С другой стороны, архитектурные сооружения, которые вынуждают проектировщиков высокого уровня знать о том, как механизмы (наследования, полиморфизма) работают на низком уровне - это попахивает нарушением инкапсуляции.

Лучше просто не связываться с такими архитектурными сооружениями следуя простому правилу:
1. Избегайте множественного наследования.
2. Избегайте глубокого наследования полиморфных интерфейсов.

А вообще, в с++ действует одно железное правило "ружья и собственной ноги". Оно гласит:

"Можно все! Если знаешь что делаешь. Если не знаешь - тогда нельзя"
0
Эксперт С++
 Аватар для fasked
5045 / 2624 / 241
Регистрация: 07.10.2009
Сообщений: 4,310
Записей в блоге: 5
24.11.2011, 10:39
Цитата Сообщение от Bers Посмотреть сообщение
Лучше просто не связываться с такими архитектурными сооружениями следуя простому правилу:
1. Избегайте множественного наследования.
2. Избегайте глубокого наследования полиморфных интерфейсов.
Как об стенку горох. Тут осталось только одно сказать: "Вы просто не умеете их готовить"
0
Делаю внезапно и красиво
Эксперт С++
 Аватар для Deviaphan
1313 / 1228 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
24.11.2011, 10:43
Цитата Сообщение от Bers Посмотреть сообщение
по сабжу, именно поэтому и происходила срезка
Там НЕТУ срезки. Перечитай приведённую тобой ссылку более внимательно. При срезке данные ТЕРЯЮТСЯ, в твоём примере ничего не теряется. "Срезанный" объект уже невозможно вернуть к исходному состоянию. Повторяю, у тебя НЕТ срезки. Срезка бывает только при использовании объектов по значению. При передаче через указатель срезки не бывает.


Цитата Сообщение от Bers Посмотреть сообщение
У человека была самодельная фабрика, которая производила объекты типа ЦЕ, а наружу выдавала указатели на А.
И уже снаружи, вызывающая сторона приводила А к чему ей было нужно, ничего не зная о том, какой в действительности был сконструирован объект самой фабрикой
У человека была ошибочно спроектирована архитектура проекта. Смысл абстрактных фабрик именно в том, чтобы не заморачиваться на счёт действительного типа объекта...


Цитата Сообщение от Bers Посмотреть сообщение
Итого: неоправданное падение производительности там, где этого можно было с лёгкостью избежать.
Именно так. Но падение производительности сперва нужно доказать.)


Цитата Сообщение от Bers Посмотреть сообщение
С другой стороны, архитектурные сооружения, которые вынуждают проектировщиков высокого уровня знать о том, как механизмы (наследования, полиморфизма) работают на низком уровне - это попахивает нарушением инкапсуляции.
Ничего подобного. Не пиши "гнилой" код и ничего низкоуровневого знать не нужно. Более того, знать о том, как работают механизмы наследования в общем случае невозможно. Как я уже написал несколько раз выше, реализация полиморфизма не стандартизирована. Важно лишь поведение, которое стандартизировано. Кривые руки и невменяемые программисты стандартом не регламентируются.

Добавлено через 56 секунд
Цитата Сообщение от Bers Посмотреть сообщение
Избегайте множественного наследования.
...в тех ситуациях, когда множественное наследование не нужно.
0
 Аватар для BRcr
4043 / 2333 / 292
Регистрация: 03.02.2011
Сообщений: 5,066
Записей в блоге: 10
24.11.2011, 10:53
Цитата Сообщение от Bers Посмотреть сообщение
1. Избегайте множественного наследования.
2. Избегайте глубокого наследования полиморфных интерфейсов.
Bers, вам что, приз дадут, ежели вы измором возьмете споривших с вами в этой теме?
Не надо нечего и никому избегать, и правила все эти нумерованные тоже никому не нужны...
Просто всегда нужно знать, чего делаешь, и только-то; в этой теме уже предостаточно написано, чтоб разобраться и в приведении типов, и в dynamic_cast, и в наследовании, и в таблицах функций... правила эти ваши зачем?
0
Заблокирован
24.11.2011, 10:59  [ТС]
Цитата Сообщение от Deviaphan Посмотреть сообщение
Там НЕТУ срезки.
C++
1
((B*)ptr)->Func2(); //вывод: A::Func1 Почему?
Правильный ответ: потому что срезка объекта.

Добавлено через 2 минуты
Цитата Сообщение от Deviaphan Посмотреть сообщение
Срезка бывает только при использовании объектов по значению.
Обращение к объекту по указателю - работа с самим объектом.
Работать с объектом по указателю == работать с самим объектом по значению.
При этом, если тип указателя и тип объекта, который живет на самом деле по адресу - разные, что будит? Будит срезка, или ещё какие нибудь не очень приятные приколы

Добавлено через 1 минуту
Цитата Сообщение от BRcr Посмотреть сообщение
Bers, вам что, приз дадут, ежели вы измором возьмете споривших с вами в этой теме
Вам показалось. Я ни с кем не спорю.
0
Делаю внезапно и красиво
Эксперт С++
 Аватар для Deviaphan
1313 / 1228 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
24.11.2011, 11:02
Цитата Сообщение от Bers Посмотреть сообщение
Правильный ответ: потому что срезка объекта.
Ответ не верный. Ты просто не понимаешь, что такое срезка.
Почему так происходит я уже разжевал и разложил по полочкам.
То, что ты не желаешь читать - не мои проблемы. Когда надумаешь действительно разобраться в проблеме, то перейди на третью страницу.

Добавлено через 2 минуты
Цитата Сообщение от Bers Посмотреть сообщение
При этом, если тип указателя и тип объекта, который живет на самом деле по адресу - разные, что будит? Будит срезка, или ещё какие нибудь не очень приятные приколы
Это не срезка. Срезка это потеря данных при копировании в процессе преобразования объекта дочернего класса к объекту базового. Т.е. когда копируются не все данные, а только те, которые известны в базовом классе. Так тебе понятнее? При работе по ссылке и указателю никакого копирования не происходит, соответственно и срезки быть не может в принципе.
Ты даже не можешь толком разобраться в примере, ссылку на который привёл. Там объект передаётся по значению, поэтому там и есть срезка.
0
Заблокирован
24.11.2011, 11:04  [ТС]
Цитата Сообщение от Deviaphan Посмотреть сообщение
Ответ не верный. Ты просто не понимаешь, что такое срезка
Что такое срезка по вашему?

По-моему, срезка - это когда большой объект приводится (интерпритируется) как более мелкий. И часть данных в итоге улетает в трубу.

В данном случае, компилятор считает что по указанному адресу живет объект типа A
Ну или объект типа B

На самом деле там живет объект типа C, но при обращении к объекту через указатель, компилятор воспринимает объект не как С, а как А или B.

Таким образом, объект, с которым происходит работа через левый указатель, оказывается срезанным.
0
Делаю внезапно и красиво
Эксперт С++
 Аватар для Deviaphan
1313 / 1228 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
24.11.2011, 11:14
Цитата Сообщение от Bers Посмотреть сообщение
По-моему, срезка - это когда большой объект приводится (интерпритируется) как более мелкий.
Приводится и интерпретируется это два абсолютно разных понятия.
Более того, невозможно изменять интерпретацию объектов. Интерпретировать можно лишь указатели.
Что такое приведение объекта? Это вызов копирующего конструктора. Виртуальных конструкторов не бывает, поэтому при копировании(приведении типа) копируются не все данные. Это и есть срезка.
О том, что такое срезка я уже писал выше, поэтому повторю

Цитата Сообщение от Deviaphan Посмотреть сообщение
То, что ты не желаешь читать - не мои проблемы
Добавлено через 2 минуты
Придумал, как объяснить нагляднее!
Смотри, читай, задавай вопросы.
C++
1
2
3
4
5
6
class A;
class B : public A;
 
B b;
A * a1 = &b; // нет срезки
A a2 = b; // есть срезка
Добавлено через 3 минуты
Специально для тебя Дьюхэрст написал книгу "Скользкие места C++".
Глава по "срезке" на странице 77. Если и после этого просветление тебя не посетит, то прекращай использовать наследование в любых формах. Указателями лучше тоже кончай пользоваться.
0
Заблокирован
24.11.2011, 11:19  [ТС]
Цитата Сообщение от Deviaphan Посмотреть сообщение
Что такое приведение объекта? Это вызов копирующего конструктора.
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
struct Base
{
    Base(): a(333){}
    Base( const Base& istok) { std::cout << "base\n"; }
    int a;
};
 
 
struct Derrived:public Base
{
    Derrived():Base() {}
    Derrived( const Derrived& istok): Base(istok) { std::cout << "Derrived\n"; }
};
 
 
int main()
{
    
    Derrived t;
    (Base)t; //по мнению Deviaphan  здесь
                 //должен запустится копирующий 
                 //конструктор
     
    return 0;
}

Почему же тогда не запустился копирующий конструктор, а??
Как вы можете это объяснить? Или может быть все таки, вы не правы?

А я вам объясню: объект это просто кучка байтов. Сама по себе не имеющая типа.
О том, как интерпритируется эта кучка байтов знает либо тип переменной, либо тип указателя.

И если тип указателя A, то компилятору пофегу, что на самом деле там живет C
При работе с объектом через такой указатель, компилятор будит считать, что там живет А

Это к вопросу об интерпретации данных.


Привести один тип к другому, не значит скопировать данные. Это значит сказать компилятору: интерпретируй этот объект, как объект другого типа.

При этом, при работе с "приведенным" типом так же может происходить срезка данных. Когда одни данные начинают восприниматься как другие данные, а часть данных вообще будит тупо проигнорирована.

Срезка происходит не когда данные не полностью скопированы, а тогда, когда компилятор уже "потерял" часть объекта.
0
Делаю внезапно и красиво
Эксперт С++
 Аватар для Deviaphan
1313 / 1228 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
24.11.2011, 11:29
Цитата Сообщение от Bers Посмотреть сообщение
Это к вопросу об интерпретации данных.
Почему ты думаешь, что строки 20-21 вообще есть в коде?
Интерпретация данных, это reinterpret_cast, вызвать для не скалярных типов нельзя.
Приведение типов static_cast - создание копии.
Интерпретация и приведение типа это не одно и то же.
Если строка 21 отработает, то произойдёт срезка t.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
24.11.2011, 11:29

Xmega грабли
Так понимаю, мало кто в форуме xmega занимается, но вдруг кому полезно будет. Они, конечно, описаны в даташитах, но... Мелкие отличия...

Грабли с USART_FLAG_RXNE
Решил тут создать сообщение, чтобы поделиться ошибкой, что я ловил пол дня. Есть у арма регистр, куда падает приходящая инфа в УАРТ. ...

Наступлю на те же грабли?
Здравствуйте. Регистрировал доменное имя через jino.ru, а они согласно whois использовали R01-REG-RIPN. Потом выбрал другой хостинг....

Грабли с WM_DEVICECHANGE
Потратил кучу времени на изучение структур связанных с WM_DEVICECHANGE. Все работает как надо wParam == DBT_DEVICEARRIVAL , отлавливает...

Грабли malloc/free
С динамической памятью впервой работаю, от сюда и грабли Есть структура typedef struct { uint8_t data_size; uint8_t *data;...


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

Или воспользуйтесь поиском по форуму:
60
Ответ Создать тему
Новые блоги и статьи
Программа опроса у.з. расходомера SLS-720F
Argus19 02.09.2026
Программа опроса у. з. расходомера SLS-720F Программа опрашивает один раз в минуту три ультразвуковых расходомера SLS-720F через интерфейс RS-485 по протоколу Modbus RTU. Опрашиваются регистры. . .
Hyper-V: Компьютер должен поддерживать доверенный платформенный модуль 2.0.
Maks 31.08.2026
При установке Windows 11 на виртуальную машину Hyper-V 2-го поколения вылезла такая ошибка: Решение: в параметрах виртуальной машины, в разделе "Безопасность" (Security) активировать флаг. . .
Архитектура биовида Стива в Майнкрафте: Зачем бонобо кубический каннибализм
anaschu 30.08.2026
Кубический Вагинокапитализм в Minecraft: Математический инвариант ОДУ и рок Стивов-бонобо Главная задача разработанной «Модели Всего» — наглядно продемонстрировать наличие системной «судьбы». . .
Оттачиваю умение писать js программы.
russiannick 30.08.2026
Проектом выходного дня стало написание Книги шифров Виженера. Итогом стала версия 200, синий туман. Синий туман назван так, потому что замораживает текст под собой. Нажатие синих кнопок управляют. . .
мат медиц модель 30. презентация проекта
anaschu 27.08.2026
хоп хоп хоп хидахоп, а я кладую))
Как у меня протекала болезнь
zorxor 27.08.2026
Здравствуйте, друзья! Эта запись блога предназначена именно для вас - для моих дорогих друзей, которые знали меня лично. Чтобы ответить на вопрос - а что же со мной произошло на самом деле? Я учился. . .
Нашел вот забавное видео о измерениях. Лучшее что я видел на эту тему
kumehtar 26.08.2026
ILETXiw9bMQ Основная суть и тезисы по измерениям: 0D (Нулевое измерение): точка, не имеющая длины, ширины, высоты или объема. Объект не может перемещаться в 0D. 1D (Первое измерение):. . .
[EasyBuilder Pro] Памятка по разработке для панелей Weintek
ФедосеевПавел 26.08.2026
Памятка по разработке для панелей Weintek ВВЕДЕНИЕ Ранее, при реализации проектов основное внимание уделял разработке управляющей программы для контроллера, а панели оператора доставалось время. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru