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

Виртуальная функция и возвращаемое значение

15.09.2013, 23:00. Показов 2798. Ответов 11
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Этот код нужен для разбора арифметических выражений. Пишем что-то типа "1,456+654,5*65.45", после чего в стек помещаются числа типа float и операторы типа char. Для этого создан виртуальный класс "Token", наследниками которого являются Operator и Number. Программа служит для разбора строки, и подсчета результата.

Проблема с виртуальными функциями. VS 2012 выдает:
error LNK2001: неразрешенный внешний символ ""public: virtual char __thiscall Number::getOperator(void)" (?getOperator@Number@@UAEDXZ)"
error LNK2001: неразрешенный внешний символ ""public: virtual float __thiscall Operator::getNumber(void)" (?getNumber@Operator@@UAEMXZ)"
сокращенно код
Кликните здесь для просмотра всего текста
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
// parse.cpp
#include <iostream>
#include <cstring>                   //for strlen(), etc
#include <stdlib.h> 
using namespace std;
const int LEN = 80;    //length of expressions, in characters
const int MAX = 40;    //size of stack
////////////////////////////////////////////////////////////////
  class Token                      // Абстрактный базовый класс
    {
    public:
      virtual void showOperNumber()=0; // чистая виртуальная
      virtual char getOperator()=0;             // функция
      virtual float getNumber()=0; 
 
      
    };
////////////////////////////////////////////////////////////////
  class Operator : public Token
    {
    private:
      char oper;             // Операторы +, –, *, /
    public:
      Operator(char c): oper(c)      // конструктор устанавливает значение
        {}
      void showOperNumber()    // получить значение
        {cout<<oper<<endl; }
      virtual float getNumber();
      char getOperator()
        {return oper;}
     
    };
////////////////////////////////////////////////////////////////
  class Number : public Token
    {
    private:
      float fnum;            // число
    public:
      Number(float f): fnum(f)         // конструктор устанавливает значение
         {}
      void showOperNumber()     // получить значение
        {cout<<fnum<<endl;}
      float getNumber()
        {return fnum;}
      virtual char getOperator();
    };
////////////////////////////////////////////////////////////////////
class Stack
   {
   private:
      Token* atoken[100];    //содержит типы Operator* и Number*                  
      int top;                       //number of top of stack
   public:
      Stack()                        //constructor
         { top = 0; }
      void push(Token* var)            //put char on stack
         { atoken[++top] = var; }
      Token* pop()                     //take char off stack
         { return atoken[top--]; }
      int gettop()                   //get top of stack
         { return top; }
   };
////////////////////////////////////////////////////////////////
int main()
   {
   setlocale (LC_ALL, "russian");
   Stack s;
   char stroka [LEN]="5,093+5,032";                          //char from input string
   char chifra [LEN];  
   char Ch;                     
   float n;
   float lastval;
   char lastop;
   //cout<<" Введите выражение. ";
   //cin>>stroka;
   int len = strlen(stroka);
   int j=0;
   int i=0; 
   Token* atoken[4] = {new Operator('+'), new Number(123.123),
                       new Operator('-'), new Number(456.456)};
   for(int k=0; k<4; k++)
        atoken[k]->showOperNumber();
 
   system("pause");
   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
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
147
148
149
150
// parse.cpp
#include <iostream>
#include <cstring>                   //for strlen(), etc
#include <stdlib.h> 
using namespace std;
const int LEN = 80;    //length of expressions, in characters
const int MAX = 40;    //size of stack
////////////////////////////////////////////////////////////////
  class Token                      // Абстрактный базовый класс
    {
    public:
      virtual void showOperNumber()=0; // чистая виртуальная
      virtual char getOperator()=0;             // функция
      virtual float getNumber()=0; 
 
      
    };
////////////////////////////////////////////////////////////////
  class Operator : public Token
    {
    private:
      char oper;             // Операторы +, –, *, /
    public:
      Operator(char c): oper(c)      // конструктор устанавливает значение
        {}
      void showOperNumber()    // получить значение
        {cout<<oper<<endl; }
      virtual float getNumber();
      char getOperator()
        {return oper;}
     
    };
////////////////////////////////////////////////////////////////
  class Number : public Token
    {
    private:
      float fnum;            // число
    public:
      Number(float f): fnum(f)         // конструктор устанавливает значение
         {}
      void showOperNumber()     // получить значение
        {cout<<fnum<<endl;}
      float getNumber()
        {return fnum;}
      virtual char getOperator();
    };
////////////////////////////////////////////////////////////////////
class Stack
   {
   private:
      Token* atoken[100];    //содержит типы Operator* и Number*                  
      int top;                       //number of top of stack
   public:
      Stack()                        //constructor
         { top = 0; }
      void push(Token* var)            //put char on stack
         { atoken[++top] = var; }
      Token* pop()                     //take char off stack
         { return atoken[top--]; }
      int gettop()                   //get top of stack
         { return top; }
   };
////////////////////////////////////////////////////////////////
int main()
   {
   setlocale (LC_ALL, "russian");
   Stack s;
   char stroka [LEN]="5,093+5,032";                          //char from input string
   char chifra [LEN];  
   char Ch;                     
   float n;
   float lastval;
   char lastop;
   //cout<<" Введите выражение. ";
   //cin>>stroka;
   int len = strlen(stroka);
   int j=0;
   int i=0; 
   Number* ptrN;
   Operator* ptrO;
   for(j; j<len; j++)          //for each input character
   {
        if (stroka[j]>='0' && stroka[j]<='9' || stroka[j]==',')
        {
            while (stroka[j]>='0' && stroka[j]<='9' || stroka[j]==',')
            {
                chifra [i]=stroka[j];
                j++; i++;
                n = atof(chifra); 
            }
            ptrN = new Number(n);
            s.push(ptrN);    
        }
        else
        if(stroka[j]=='+' || stroka[j]=='-' || stroka[j]=='*' || stroka[j]=='/')
        {
            Ch = stroka[j];
            if (s.gettop()==1)
            {
                ptrO = new Operator(Ch);
                s.push(ptrO);   
            }
            else
            {
                lastval=s.pop()->getNumber();
                lastop=s.pop()->getOperator();
                if( (stroka[j]=='*' || stroka[j]=='/') && (lastop=='+' || lastop=='-') )
                {
                    ptrO = new Operator(lastop);
                    s.push(ptrO);   
                    ptrN = new Number(lastval);
                    s.push(ptrN);   
               }
               else                     //in all other cases
               {
               switch(lastop)        //do last operation
                  {                  //push result on stack
                  case '+': ptrN = new Number(s.pop()->getNumber() + lastval); break;
                  case '-': ptrN = new Number(s.pop()->getNumber() - lastval); break;
                  case '*': ptrN = new Number(s.pop()->getNumber() * lastval); break;
                  case '/': ptrN = new Number(s.pop()->getNumber() / lastval); break;
                  default:  cout << "\nUnknown oper"; exit(1);
                  }  //end switch
               }  //end else, in all other cases
            ptrO = new Operator(stroka[j]);
            s.push(ptrO);              //put current op on stack
            }  //end else, not first operator
         }  //end else if, it's an operator
   
      else                           //not a known character
         { cout << "\nUnknown input character"; exit(1); }
   }
//--------------------------------------------------------------
 
    while(s.gettop() > 1)
      {
      lastval = s.pop()->getNumber();//get previous value
      switch( s.pop()->getOperator() )              //get previous operator
         {                           //do operation, push answer
         case '+': new Number(s.pop()->getNumber() + lastval); break;
         case '-': new Number(s.pop()->getNumber() - lastval); break;
         case '*': new Number(s.pop()->getNumber() * lastval); break;
         case '/': new Number(s.pop()->getNumber() / lastval); break;
         default:  cout << "\nUnknown operator"; exit(1);
         }  //end switch
      }  //end while
   s.pop()->showOperNumber();
   system("pause");
   return 0;
   }


как правильно описать ?
C++
1
virtual char getOperator()=0; virtual float getNumber()=0;
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
15.09.2013, 23:00
Ответы с готовыми решениями:

Шаблонная Функция: возвращаемое значение должно быть такого же типа, как входящее
Добрый день всем. Помогите разобраться в шаблонах. template&lt;typename X&gt; double mean(const X *x,int n) { int s = 0; int i; ...

Чистая виртуальная функция функция не имеет оператора переопределения
Пишу программу для записи заметок. Есть 2 класса: Page и Note. Note наследуется от Page. Page.h #pragma once ...

Возвращаемое значение
Как сделать так, что бы в зависимости от подаваемых аргументов, функция возвращала разные значения? Пробовал через шаблоны, но не...

11
What a waste!
 Аватар для gray_fox
1610 / 1302 / 180
Регистрация: 21.04.2012
Сообщений: 2,733
15.09.2013, 23:28
Рики, что бы собралось, можно сделать "пустую" реализацию.
C++
1
virtual float getNumber() { return 0; }
Но вообще плохой интерфейс.
0
Каратель
Эксперт С++
6610 / 4029 / 401
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
15.09.2013, 23:30
Цитата Сообщение от Рики Посмотреть сообщение
Проблема с виртуальными функциями. VS 2012 выдает:
error LNK2001: неразрешенный внешний символ ""public: virtual char __thiscall Number::getOperator(void)" (?getOperator@Number@@UAEDXZ)"
error LNK2001: неразрешенный внешний символ ""public: virtual float __thiscall Operator::getNumber(void)" (?getNumber@Operator@@UAEMXZ)"
где реализации
Number::getOperator(void)
Operator::getNumber(void)
?
тело у них должно быть
0
6 / 6 / 0
Регистрация: 27.02.2013
Сообщений: 23
16.09.2013, 02:39  [ТС]
C++ (Qt)
1
virtual float getNumber() { return 0; }
Да, в упрощенном варианте работает, но в полной версии нет.
Наверное, нужно было только полный текст листинга приводить.

Но вообще плохой интерфейс.
Согласен, но лучше сначала запустить, а лоск и потом можно навести.

где реализации
Number::getOperator(void)
Operator::getNumber(void)
А что там прописывать? Если бы значение не возвращало, то можно было бы просто написать :
C++
1
 virtual void getNumberOperator();
а так, даже не знаю. Если из класса, например, "Operator" убрать "virtual float getNumber();", он становится абстрактным. Как можно решить эту проблему?
0
What a waste!
 Аватар для gray_fox
1610 / 1302 / 180
Регистрация: 21.04.2012
Сообщений: 2,733
16.09.2013, 02:50
Цитата Сообщение от Рики Посмотреть сообщение
Если из класса, например, "Operator" убрать "virtual float getNumber();", он становится абстрактным. Как можно решить эту проблему?
Реализовать все виртуальные методы: getNumber - в Operator, getOperator - в Number.
Цитата Сообщение от Рики Посмотреть сообщение
Согласен, но лучше сначала запустить, а лоск и потом можно навести.
Просто если некоторые операции в наследниках не нужны, то не понятно, зачем тогда реализовывать этот интерфейс (здесь наследоваться от Token).
0
6 / 6 / 0
Регистрация: 27.02.2013
Сообщений: 23
16.09.2013, 02:59  [ТС]
Цитата Сообщение от gray_fox Посмотреть сообщение
Реализовать все виртуальные методы: getNumber - в Operator, getOperator - в Number.
Да, но как это грамотно сделать? Если прописать
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Operator : public Token
    {
    private:
      char oper;             // Операторы +, –, *, /
    public:
      Operator(char c): oper(c)      // конструктор устанавливает значение
        {}
      void showOperNumber()    // получить значение
        {cout<<oper<<endl; }
      virtual float getNumber()
        { return fnum; }
      char getOperator()
        {return oper;}
     
    };

в этом классе не будет "fnum".
0
What a waste!
 Аватар для gray_fox
1610 / 1302 / 180
Регистрация: 21.04.2012
Сообщений: 2,733
16.09.2013, 03:07
Цитата Сообщение от Рики Посмотреть сообщение
Да, но как это грамотно сделать?
Грамотно: нужен другой подход - дизайн, если хочешь.
Что бы скомпилировалось: поставить заглушку:
C++
1
virtual float getNumber() { return 0.f; }
Добавлено через 1 минуту
Цитата Сообщение от Рики Посмотреть сообщение
в этом классе не будет "fnum".
В том то и дело, зачем этот метод вообще нужен? Если ты реализуешь Token, значит он вроде как тебе нужен...
1
6 / 6 / 0
Регистрация: 27.02.2013
Сообщений: 23
16.09.2013, 03:44  [ТС]
Переделал.
Кликните здесь для просмотра всего текста
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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
// parse.cpp
#include <iostream>
#include <cstring>                   //for strlen(), etc
#include <stdlib.h> 
using namespace std;
const int LEN = 80;    //length of expressions, in characters
const int MAX = 40;    //size of stack
////////////////////////////////////////////////////////////////
  class Token                      // Абстрактный базовый класс
    {
    public:
      virtual void showOperNumber()=0; // чистая виртуальная
      virtual char getOperator()=0;             // функция
      virtual float getNumber()=0; 
 
      
    };
////////////////////////////////////////////////////////////////
  class Operator : public Token
    {
    private:
      char oper;             // Операторы +, –, *, /
    public:
      Operator(char c): oper(c)      // конструктор устанавливает значение
        {}
      void showOperNumber()    // получить значение
        {cout<<oper<<endl; }
      virtual float getNumber()
        { return 0.f; }
      char getOperator()
        {return oper;}
     
    };
////////////////////////////////////////////////////////////////
  class Number : public Token
    {
    private:
      float fnum;            // число
    public:
      Number(float f): fnum(f)         // конструктор устанавливает значение
         {}
      void showOperNumber()     // получить значение
        {cout<<fnum<<endl;}
      float getNumber()
        {return fnum;}
      virtual char getOperator()
        { return 0.f; }
    };
////////////////////////////////////////////////////////////////////
class Stack
   {
   private:
      Token* atoken[100];    //содержит типы Operator* и Number*                  
      int top;                       //number of top of stack
   public:
      Stack()                        //constructor
         { top = 0; }
      void push(Token* var)            //put char on stack
         { atoken[++top] = var; }
      Token* pop()                     //take char off stack
         { return atoken[top--]; }
      int gettop()                   //get top of stack
         { return top; }
   };
////////////////////////////////////////////////////////////////
class express
{
    private:
        Stack s;
        char* pStr;
        int len;
    public:
        express (char* ptr)
        {
            pStr=ptr;
            len =strlen(pStr);
        }
        void parse ();     // разбор выражения
        float solve ();      // получение результата
};
//--------------------------------------------------------------
void express::parse()
{
    char chifra [LEN];    //символы из строки
    float lastval;        // последнее значение
    char lastop;          // последний оператор
    Token* atoken[100];
    Number* ptrN;
    Operator* ptrO;
    float n;
    char Ch;  
    int j=0;
    int i=0; 
 
    for(j; j<len; j++)          //для всех символов в строке
    {
        if (pStr[j]>='0' && pStr[j]<='9' || pStr[j]==',')
        {
            while (pStr[j]>='0' && pStr[j]<='9' || pStr[j]==',')  // получаем число 
            {
                chifra [i]=pStr[j];
                j++; i++;
                n = atof(chifra); 
            }
            ptrN = new Number(n);
            s.push(ptrN);                                       // заносим  в стек
        }
        else
        if(pStr[j]=='+' || pStr[j]=='-' || pStr[j]=='*' || pStr[j]=='/')
        {
            Ch = pStr[j];
            if (s.gettop()==1)                                    // если это первый оператор, то помещаем в стек
            {
                ptrO = new Operator(Ch);
                s.push(ptrO);   
            }
            else
            {
                lastval=s.pop()->getNumber();                //получение предыдущего числа
                lastop=s.pop()->getOperator();              //получение предыдущего оператора
                // если это * или / , а предыдущий был + или -, то
                if( (pStr[j]=='*' || pStr[j]=='/') && (lastop=='+' || lastop=='-') )
                {
                    ptrO = new Operator(lastop);   //отменяем последние два взятия из стека
                    s.push(ptrO);   
                    ptrN = new Number(lastval);
                    s.push(ptrN);   
               }
               else                     //помещаем в стек текущий оператор 
               {
               switch(lastop)        
                  {                  
                  case '+': ptrN = new Number(s.pop()->getNumber() + lastval); break;
                  case '-': ptrN = new Number(s.pop()->getNumber() - lastval); break;
                  case '*': ptrN = new Number(s.pop()->getNumber() * lastval); break;
                  case '/': ptrN = new Number(s.pop()->getNumber() / lastval); break;
                  default:  cout << "\nUnknown oper"; exit(1);
                  }  
               }  
            ptrO = new Operator(pStr[j]);
            s.push(ptrO);              //помещаем в стек текущий оператор 
            }  
         }  
   
      else                           //что-то левое
         { cout << "\nUnknown input character"; exit(1); }
   }
}
//-------------------------------------------------------------
float express::solve ()  //убираем данные из стека
{
    float lastval;              
    while(s.gettop() > 1)
      {
      lastval = s.pop()->getNumber();               //предыдущее значение 
      switch( s.pop()->getOperator() )              //получение предыдущего оператора
         {                           //do operation, push answer
         case '+': new Number(s.pop()->getNumber() + lastval); break;
         case '-': new Number(s.pop()->getNumber() - lastval); break;
         case '*': new Number(s.pop()->getNumber() * lastval); break;
         case '/': new Number(s.pop()->getNumber() / lastval); break;
         default:  cout << "\nUnknown operator"; exit(1);
         }  
      }  
   return float (s.pop()->getNumber());//последний оператор в стеке это результат
}
////////////////////////////////////////////////////////////////
 
int main()
   {
   setlocale (LC_ALL, "russian");
   char stroka [LEN]="5,093+5,032";                         
   express* eptr = new express (stroka);
   eptr->parse();
   cout <<"\nРезультат: "
       << eptr->solve();
   delete eptr;
   system("pause");
   return 0;
   }

Результата нет.
Буду благодарен совет.

ps "0.f"- что это значит? как понять эту заглушку?
0
бжни
 Аватар для alex_x_x
2473 / 1684 / 135
Регистрация: 14.05.2009
Сообщений: 7,162
16.09.2013, 04:00
Цитата Сообщение от Рики Посмотреть сообщение
ps "0.f"- что это значит? как понять эту заглушку?
0. - это валидное представление нуля с плавающей точкой (ровно как и .0)
f - literal suffix (уж не помню как это по-русски) для float, означает, что эта константа будет типа float
0. - будет double

http://www.cplusplus.com/doc/tutorial/constants/
1
6 / 6 / 0
Регистрация: 27.02.2013
Сообщений: 23
18.09.2013, 06:50  [ТС]
Спасибо за содействие. Запустил, все работает как надо.
Хотя, так и не разобрался с этими заглушками.
я поставил
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Number : public Token
    {
    private:
      float fnum;            // число
    public:
      Number(float f): fnum(f)         // конструктор устанавливает значение
         {}
      void showOperNumber()     // получить значение
        {cout<<fnum<<endl;}
      float getNumber()
        {return fnum;}
      virtual char getOperator()
        { return 0.f; }
    };

почему не выдавало ошибку в return 0.f; когда мы должны возвратить char?
И еще одно: что лучше писать в тех функциях, которые необходимо заполнить дабы порожденный класс не был виртуальным, а по факту эти функции в классе не нужны?
0
Каратель
Эксперт С++
6610 / 4029 / 401
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
18.09.2013, 23:01
Цитата Сообщение от Рики Посмотреть сообщение
И еще одно: что лучше писать в тех функциях, которые необходимо заполнить дабы порожденный класс не был виртуальным, а по факту эти функции в классе не нужны?
бросить исключение
0
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
18.09.2013, 23:06
Цитата Сообщение от Рики Посмотреть сообщение
а по факту эти функции в классе не нужны
Скорее всего нужно пересмотреть иерархию.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
18.09.2013, 23:06
Помогаю со студенческими работами здесь

Виртуальная функция
Ругается на метод virtual bool isOveersize() из класса publication. Что не так ? #include &quot;stdafx.h&quot; #include &lt;string&gt; ...

Виртуальная функция
Создайте класс Matematica, определите в нем виртуальную функцию-член matem(int x, int y), которая выводит на экран значения параметров....

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

Виртуальная функция
Всем доброго времени суток! Прошу помочь с одной проблемой. Собственно, вот программа: #include &lt;iostream&gt; #include...

Виртуальная функция
Создать производный класс Trapez(равнобокая трапеция). Определить в классе наследнике: -перегруженные функции для изменения сторон ...


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

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
Новые блоги и статьи
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
Управление камерой с помощью скрипта OrbitControls.js на Three.js: Вращение, зум и панорамирование
8Observer8 05.03.2026
Содержание блога Финальная демка в браузере работает на Desktop и мобильных браузерах. Итоговый код: orbit-controls-threejs-js. zip. Сканируйте QR-код на мобильном. Вращайте камеру одним пальцем,. . .
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip На первой гифке отладочные линии отключены, а на второй включены:. . .
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip Сканируйте QR-код на мобильном и вы увидите, что появится джойстик для управления главным героем. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru