Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.62/21: Рейтинг темы: голосов - 21, средняя оценка - 4.62
"C with Classes"
2022 / 1404 / 523
Регистрация: 16.08.2014
Сообщений: 5,885
Записей в блоге: 1

Чем заменить указатель

05.07.2020, 10:39. Показов 4740. Ответов 48
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Чем заменить можно указатель в данном примере. Что бы можно было использовать p как объект без операции разыменования?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <queue>
 
class SomeСlass
{
private:
    using Container = std::queue<int>;
    Container * p;
 
public:
    SomeСlass() : p{nullptr} {}
    SomeСlass(Container & r) : p{&r} {}
 
    void Reset(Container & r)
    {
        p = &r;
    }
};
Добавлено через 6 минут
подозреваю, что использовать указатель в данном случае оптимальное и единственное решение, можно было бы использовать ссылку Container & если бы не было функции члена Reset
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
05.07.2020, 10:39
Ответы с готовыми решениями:

Указатель или ссылка на указатель. В чем разница?
Есть вопрос про указатели и ссылки на указатели :scratch: Хочу в функциях f1() и в f2() динамически выделить память и возвратить этот...

Чем отличаются указатель на строку и константный указатель на строку?
Просто обьясните, как такое возможно? char *a=&quot;fff&quot;; В чем отличие от этого? : const char *a=&quot;fff&quot;; Ведь так и так...

Указатель на указатель, в чем смысл?
BOOL WTSEnumerateProcesses( _In_ HANDLE hServer, _In_ DWORD Reserved, _In_ DWORD Version, _Out_ PWTS_PROCESS_INFO...

48
"C with Classes"
2022 / 1404 / 523
Регистрация: 16.08.2014
Сообщений: 5,885
Записей в блоге: 1
05.07.2020, 16:34  [ТС]
Студворк — интернет-сервис помощи студентам
Undisputed, Avazart, hoggy, спасибо за участие
0
 Аватар для Fulcrum_013
2083 / 1574 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
05.07.2020, 16:40
_stanislav, Тут в общем вопрос касательно взаимосвязей в ООП по большому счету. Их два вида - композиция - обьект является составной частью и уничтожается вместе с хозяином, и агрегация -объект является составной частью другого объекта, ваш же объект только пользуется им в случае если такой есть - т.е. помереть может собственной смертью вне зависимости от ваших на него ссылок . Вы тут используете агрегацию. Т.е. по определению должны быть готовы к тому что кто то сторонний может уничтожить объект на который вы ссылаетесь. Разрулить ситуацию можно двумя вариантами - либо действительно weak_ptr (цена - лок при каждом обращении) либо интрузивные двунаправленные указатели (цена - более сложная реализация, в универсальном варианте - оверхед по памяти указателей от 2x, но оповещение о смерти объекта однократное).
Ну либо пересмотреть архитектуру в направление композиции очереди в ваш объект/обращения к очереди через ее хозяина.
0
Эксперт С++
 Аватар для Avazart
8484 / 6151 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
05.07.2020, 16:41
Можно к примеру так использовать
C++
1
SomeСlass some(new Container);
Подразумевая передачу владения и тогда уместен unique_ptr.
Или когда у нас Containe расшаривается между несколькими SomeСlassX и тогда соответственно shared_ptr.
0
"C with Classes"
2022 / 1404 / 523
Регистрация: 16.08.2014
Сообщений: 5,885
Записей в блоге: 1
05.07.2020, 17:07  [ТС]
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Т.е. по определению должны быть готовы к тому что кто то сторонний может уничтожить объект на который вы ссылаетесь.
пока нет в этом нужды

Добавлено через 3 минуты
Класс который передает в SomeСlass буфер, заинтересован в том что бы SomeСlass обработал этот буфер, зачем ему затирать буфер? Вообщем то класс который передает в SomeСlass буфер только и делает что заполняет этот буфер и передает на обработку в SomeСlass

Добавлено через 22 минуты
точнее некий класс буферезирует данные которые SomeСlass уже использует через указатель.
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
05.07.2020, 17:10
Цитата Сообщение от Undisputed Посмотреть сообщение
std::stack:op не делается проверка на то что есть ли элемент в стеке или нет. Это как бы оставляют на конечного пользователя тем самым не создают оверхед но при этом оставляют конечному пользователю возможность сделать эту проверку самому хотя они могли бы например возвращать bool как результат операции удаления типа удалилось или нет и не вводить UB если контейнер окажется пустым (вот что я имел ввиду когда говорил про оверхед при навязывании безопасного обращения с объектами).
не понятно, нафиг нужен этот буль.

уважающая себя, хорошо воспитанная программа не должна делать бессмысленных вещей.

если очередь пуста, тогда в принципе ничего удалять из неё не нужно.

Кликните здесь для просмотра всего текста

фрагмент из реального продакшен кода.
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
    bool task_queue::run_once()
    {
        task_queue::task task;
        {
            ::std::lock_guard<decltype(this->m_mutex)>
                lock(this->m_mutex);
 
            if(!this->m_tasks.empty())
            {
                task = ::std::move(this->m_tasks.front());
                this->m_tasks.pop();
            }
            else
                return false;
        }
 
        try
        {
            task();
        }
        catch(const ::std::exception& e)
        {
            this->error(e.what());
        }
        catch(...)
        {
            this->error("unknown exception");
            assert(0 && "unknown exception");
        }
        return true;
    }


как у тебя вообще, хотя бы чисто теоретически может возникнуть ситуация,
когда ты вынужден опираться на этот буль?
вот объясни мне: как это вообще возможно?

ты что, пишешь код по принципу: "сначала делаем, и только потом думаем?"

C++
1
2
ты копай тут, а ты - тут, и тут. а я пока пойду, и узнаю, где нужно копать
(ц) армейский юмор.

Цитата Сообщение от Undisputed Посмотреть сообщение
Что касается того что "ресурс всегда должен быть валидным когда он нужен и если его нет то это программная ошибка и weak_ptr не поможет" то тут я не согласен. Мы ведь может вызвать use_count для weak_ptr при уточнённом объекте на который был нацелен соответствующий shared и это не будет UB и никаких программных ошибок не будет. Если use_count == 0, можем бросить эксепшен.
здрасти-приехали.

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

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

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




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


не будет он работать.
0
 Аватар для zayats80888
6352 / 3523 / 1428
Регистрация: 07.02.2019
Сообщений: 8,995
05.07.2020, 17:39
Цитата Сообщение от _stanislav Посмотреть сообщение
Вообщем то класс который передает в SomeСlass буфер только и делает что заполняет этот буфер и передает на обработку в SomeСlass
А не лучше ли тогда и передавать владение(std::move или через unique_ptr, если контейнер не поддерживает семантику перемещения), и забрать после?
0
"C with Classes"
2022 / 1404 / 523
Регистрация: 16.08.2014
Сообщений: 5,885
Записей в блоге: 1
05.07.2020, 17:44  [ТС]
Цитата Сообщение от zayats80888 Посмотреть сообщение
А не лучше ли тогда и передавать владение
оверхед
Цитата Сообщение от zayats80888 Посмотреть сообщение
если контейнер не поддерживает семантику перемещения
unique поддерживает семантику перемещения
0
 Аватар для zayats80888
6352 / 3523 / 1428
Регистрация: 07.02.2019
Сообщений: 8,995
05.07.2020, 17:47
Цитата Сообщение от _stanislav Посмотреть сообщение
оверхед
Да я бы не сказал, зато при добавлении многопоточности меньше рефакторить, имхо.
Цитата Сообщение от _stanislav Посмотреть сообщение
unique поддерживает семантику перемещения
А я о чём?
0
901 / 478 / 93
Регистрация: 10.06.2014
Сообщений: 2,700
05.07.2020, 17:47
Цитата Сообщение от hoggy Посмотреть сообщение
если очередь пуста, тогда в принципе ничего удалять из неё не нужно.
я понимаю о чем ты говоришь и в целом то что ты говоришь это как раз хорошо в плане гибкости - то есть мы сами решаем делать проверку или нет (т.е нас не кто не обязывает на постоянной основе делать проверки)... но тем не менее, отвечая на твой вопрос
Цитата Сообщение от hoggy Посмотреть сообщение
нафиг нужен этот буль
можно написать такой код:
C++
1
if (stack.pop()){std::cout << "Removed";}
этот код проще чем аналогичный ему по смыслу такой вот код:
C++
1
2
3
4
if(!stack.empty()) {
    stack.pop();
    std::cout << "Removed";
}
вот для упрощения кода например этот буль может быть нужен
и прежде чем ты назовешь этот код плохим названием скажу что я в этой теме не защищаю какой либо подход
а лишь рассматриваю в принципе возможные варианты, их плюсы и минусы

Цитата Сообщение от hoggy Посмотреть сообщение
твой класс должен обработать данные, которые внезапно протухли.
если это ситуация где подобного не должно быть то да, это уже баг
но если скажем твой ресурс это некий endpoint, который не спрашивая тебя может закрыть соединение с тобой, то это уже не баг. и вот мы как бы можем проверить а открыто ли еще соединение. если да - то работаем. если нет - то не работаем. и это нормально в рамках нашей задачи.
0
"C with Classes"
2022 / 1404 / 523
Регистрация: 16.08.2014
Сообщений: 5,885
Записей в блоге: 1
05.07.2020, 17:55  [ТС]
Цитата Сообщение от zayats80888 Посмотреть сообщение
Да я бы не сказал, зато при добавлении многопоточности меньше рефакторить, имхо.
интересно

Добавлено через 3 минуты
zayats80888, для большей универсальности класса SomeClass лучше наверное принимать буфер по значению с перемещением.

Добавлено через 3 минуты
Цитата Сообщение от _stanislav Посмотреть сообщение
для большей универсальности класса SomeClass лучше наверное принимать буфер по значению с перемещением.
что бы зацепление ослабить
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
05.07.2020, 18:24
Цитата Сообщение от Undisputed Посмотреть сообщение
if (stack.pop()){std::cout << "Removed";}
по-моему, это - какой то бред.
такое впечатление, что автору кода совершенно пофигу:
будет ли в итоге удален элемент, или нет.
всвязи с чем совершенно не понятно:
зачем вообще он пытается удалить элемент из очереди?

Цитата Сообщение от Undisputed Посмотреть сообщение
if(!stack.empty()) {
    stack.pop();
    std::cout << "Removed";
}
дело не в том: проще или нет.
дело в здравом смысле.
дело в ответе на вопрос: зачем удаляем?

здесь по смыслу - все тоже самое, что и в первом варианте.


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

ещё раз:
сначала выясняем: а нужно ли вообще обрабатывать?
и только потом удаляем кандидат-отработанный элемент.


удалять просто ради удаления - это какой то бред.


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

все без исключения.
во всех в этих ситуациях ссылка должна оставаться валидной.
иначе алгоритм в принципе не сможет работать.
0
"C with Classes"
2022 / 1404 / 523
Регистрация: 16.08.2014
Сообщений: 5,885
Записей в блоге: 1
05.07.2020, 18:34  [ТС]
вот объявление класса SomeClass если кому интересно:
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
#pragma once
 
#include <string>
#include <queue>
#include <forward_list>
 
#include "Token.h"
#include "LexemeState.h"
#include "TableOfSymbols.h"
 
namespace clc::prs::lxr
{
    class Lexer
    {
    private:
        using WChar = std::wstring::value_type;
 
        LexemeState lexemeState;
        std::queue<WChar> * expression;
 
        TableOfSymbols<> tableOfSymbols;
 
        TokenEnum pastToken{Empty};
        bool IsUnary(TokenEnum);
 
        Token RefineToken(TokenEnum, std::wstring &);
 
        TokenEnum RefineFunction(std::wstring &);
        TokenEnum RefineOperation(WChar);
 
        std::forward_list<std::wstring> functionNames;
 
    public:
        Lexer();
        Lexer(std::queue<WChar> &, std::initializer_list<std::wstring> l =
                {L"sin", L"cos", L"tan", L"sqrt",} );
 
        Lexer(Lexer const &) = delete;
        Lexer(Lexer &&) = default;
 
        ~Lexer() = default;
 
        Lexer & operator=(Lexer const &) = delete;
        Lexer & operator=(Lexer &&) = default;
 
        Token GetToken();
 
        void Reset(std::queue<WChar> &);
        operator bool();
 
        TableOfSymbols<> & GetTableOfSymbol();
    };
 
    inline Lexer::Lexer() : expression{nullptr} {}
 
    inline Lexer::Lexer(
        std::queue<WChar> & i,
        std::initializer_list<std::wstring> l) :
            expression{&i},
            functionNames{l} {}
 
    inline void Lexer::Reset(std::queue<WChar> & q)
    {
        expression = &q;
        tableOfSymbols.Clear();
        pastToken = Empty;
    }
 
    inline Lexer::operator bool()
    {
        return expression != nullptr && !expression->empty();            
    }
 
    inline TableOfSymbols<> & Lexer::GetTableOfSymbol()
    {
        return tableOfSymbols;
    }
}
0
261 / 111 / 53
Регистрация: 22.01.2017
Сообщений: 448
05.07.2020, 18:34
Цитата Сообщение от Undisputed Посмотреть сообщение
тогда будет срабатывать оператор присваивания копированием (к чему лишние копии?)
Это понятно, move придется реализовать. Я к вопросу об указателе, на сколько он принципиален.

Не по теме:

Сам не люблю контейнер через указатель дергать.

0
901 / 478 / 93
Регистрация: 10.06.2014
Сообщений: 2,700
05.07.2020, 18:55
Цитата Сообщение от hoggy Посмотреть сообщение
такое впечатление, что автору кода совершенно пофигу
почему это пофигу? автор смотрит если есть вершина то удаляет ее и выдает репорт

Цитата Сообщение от hoggy Посмотреть сообщение
дело не в том: проще или нет.
ну я именно сейчас говорю про то что так проще и если где-то нам нужно удалять из контейнера и с проверкой перед удалением, то проверку можно организовать по разному и в каком то случае код может быть короче но с сохранением сути - вот что я говорю... и если скажем тебе в 10 местах нужно перед удалением проверить контейнер на пустоту (или типичный find + erase) то упаковка проверки в метод позволит не только сократить код в локальном участке, это так же избавит от необходимости дублировать эти проверки во всех 10 местах...

Цитата Сообщение от hoggy Посмотреть сообщение
все случаи работы с очередями сводились к тому
ок пусть это будет не стек... посмотри std::map::erase (перегрузка которая удаляет элемент по ключу).
она как раз таки возвращает количество удаленных элементов (если 0 - значит ничего не удалили).
вот есть такой вариант удаления элемента по ключу (если он есть)
C++
1
2
3
4
std::map<int,int> m{{1,2},{3,4}};
if (m.erase(3) != 0) {
    std::cout << "erased\n";
}
а есть такой вариант
C++
1
2
3
4
5
auto it = m.find(1);
if (it != m.end()) {
    m.erase(it);
    std::cout << "erased\n";
}
из примера выше следует что такой подход местами используется в том числе и в стандартной библиотеке

то есть в одном случае мы опираясь на возвращаемое значение метода который отвечает за удаление выдаем репорт
а в другом случае мы сначала проверяем есть ли элемент а потом удаляем его и выдаем репорт
суть одна и та же просто первый вариант более краток
причем в случае std::map::erase(key) у нас 2 варианта: возвращаемое значение либо 0 либо 1 (т.к ключи уникальные) что в принципе как раз таки намекает на bool

Добавлено через 3 минуты
Цитата Сообщение от n1b1ru Посмотреть сообщение
move придется реализовать
все равно с move тоже скорее всего будут лишние операции (обычно конструктор перемещения это больше чем копирование значения единственного указателя)
1
 Аватар для Fulcrum_013
2083 / 1574 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
05.07.2020, 19:04
_stanislav, Ну здесь по всей видимости стоит пересмотреть а насколько нужно выдергивать токены по одному. Возможно стоит посмотреть в сторону того, что лексер преобразовывает сразу всю входную строку в строку токенов, потом работает уже с ней. Такая строка токенов и гораздо меньше (ну к примеру для glext.h что то около 75k токенов на мегабайт текста) - т.е. работа с ней будет гораздо быстрее, ну и в результате и с указателем чужим геморроя нет и к кешу более дружелюбно будет однозначно.
0
"C with Classes"
2022 / 1404 / 523
Регистрация: 16.08.2014
Сообщений: 5,885
Записей в блоге: 1
05.07.2020, 19:09  [ТС]
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Ну здесь по всей видимости стоит пересмотреть а насколько нужно выдергивать токены по одному.
спасибо за совет
0
261 / 111 / 53
Регистрация: 22.01.2017
Сообщений: 448
05.07.2020, 19:31
Undisputed, на сколько правильна следующая реализация (оставим пока эффективность, ну и move assignment):
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
class SomeClass {
private:
    using Container = std::queue<int>;
    Container p;
 
public:
    SomeClass() {}
    SomeClass(Container & r) : p{r} {}
    SomeClass(Container && r) : p{std::move(r)} {}
    
    void Reset(Container & r) {
        p = r;
    }
 
    void Reset(Container && r) {
        p = std::move(r);
    }
};
 
std::queue<int> getQueue(std::initializer_list<int> lst) {
    std::queue<int> q;
    for(const int& el: lst) {
        q.push(el);
    }
    
    return q;
}
 
int main() {
    SomeClass s(getQueue({ 1, 2, 3, 4, 5 }));
    auto q = getQueue({ 1, 2, 3, 4, 5 });
    s.Reset(q);
    s.Reset(getQueue({ 1, 2, 3, 4, 5 }));
}
0
901 / 478 / 93
Регистрация: 10.06.2014
Сообщений: 2,700
05.07.2020, 19:35
n1b1ru,
Я ещё забыл отметить, что в случае с move будет испорчен исходный объект что может быть неприемлемо в конкретной ситуации.

А на сколько правильный код о котором вы спросили уже зависит от конкретной задачи. Это зависит от того что вы пытаетесь получить в конечном счёте.
0
261 / 111 / 53
Регистрация: 22.01.2017
Сообщений: 448
05.07.2020, 19:44
Undisputed, задача реализовать композицию.
Цитата Сообщение от Undisputed Посмотреть сообщение
Я ещё забыл отметить, что в случае с move будет испорчен исходный объект что может быть неприемлемо в конкретной ситуации.
В моем случае исходный объект временный.
0
"C with Classes"
2022 / 1404 / 523
Регистрация: 16.08.2014
Сообщений: 5,885
Записей в блоге: 1
05.07.2020, 19:47  [ТС]
Цитата Сообщение от n1b1ru Посмотреть сообщение
SomeClass(Container && r)
а тут ты что хотел сказать?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
05.07.2020, 19:47
Помогаю со студенческими работами здесь

сма DAEWOO DWD M1029A чем заменить транс, трансформатор в обрыве, чем заменить
день добрый. модуль PN:361430A950 первичная транса в обрыве . может кто подскажет параметры , или советом о замене . есть лыжевский на...

Чем плохой указатель на void?
Здравствуйте! Недавно прочитал статью на хабре http://habrahabr.ru/post/102930/ Сабж - архитектура игрового двигла, а именно менеджер...

Итератор и указатель в чем разница
Здравствуйте, Подскажите пожалуйста, вот есть такое определение: Для получения итераторов контейнеры в C++ обладают такими...

Чем можно заменить заменить toggle() ?
Добрый день, у меня такой вопрос. Чем можно заменить toggle(function(), function()); В ранних версиях toggle можно было использовать как...

Как заменить переменную i на указатель?
вычисляю факториал числа. нужно заменить переменные на указатели. две переменные заменил, прога работает. третья переменная (i) пока не...


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

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Новые блоги и статьи
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