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

Полиморфизм и доступ к полям потомков

17.02.2015, 23:04. Показов 4980. Ответов 21
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Задача: накидать в окне прямоугольники и круги, а потом упаковать их максимально плотно. Делаем в Qt. Структура классов такая: есть базовый класс Shape, и от него наследуются классы прямоугольников Rect и кругов Circle.
Код:

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
class Shape{
 
};
 
class Rect: public Shape{
private:
    int x1, y1; //Левый верхний угол
    int x2, y2; //Правый нижний угол
public:
    Rect();
    //Построение по диагональным точкам
    Rect(int x1, int y1, int x2, int y2);
};
Реализация:

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
#include "rectangle.h"
 
Rect::Rect(){
    x1 = 0; y1 = 0;
    x2 = 0; y2 = 0;
}
 
Rect::Rect(int x1, int y1, int x2,int y2){
    this->x1 = x1;
    this->y1 = y1;
    this->x2 = x2;
    this->y2 = y2;
}
Экземпляры фигур хранятся в самодельном векторе Shape'ов и добавляются по второму клику так:

C++ (Qt)
1
shapes.append(new Rect(angles.x1, angles.y2, angles.x2, angles.y2));
Функция отрисовки:

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
void MainWindow::paintEvent(QPaintEvent *p){
    qDebug() << "paintEvent";
    if(allowPainting == 1){
        qDebug() << "painting...";
        QPainter painter(this);
        for(int i = 0; i < shapes.size(); i++){
            int width = abs(shapes[i].x2 - shapes[i].x1);
            int height = abs(shapes[i].y2 - shapes[i].y1);
            painter.drawRect(shapes[i].x1, shapes[i].y1, width, height);
        }
    }
}
И здесь у меня возникает ошибка 'class Shape' has no member named 'x2' и такое же сообщения о недоступности всех остальных координат. Почему возникает эта ошибка? Здесь же используется полиморфизм - вектор Shape'пов может хранить любые классы, порожденные от него, почему он обязательно должен содержать внутренности своих потомков?

Как это исправить?

И почему наследование надо обязательно делать public, иначе возникает ошибка?
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
17.02.2015, 23:04
Ответы с готовыми решениями:

Выведите номера вершин, у которых количество потомков в левом поддереве не равно количеству потомков в правом
Выведите номера вершин, у которых количество потомков в левом поддереве не равно количеству потомков в правом поддереве. Не могли бы...

Доступ к полям
Подскажите пожайлуста!!!! Есть например форма, туды набиваются какте-то данные, возможно ли определенным пользователям запрещать или...

Доступ к полям класса
Имеет список list с объектами класса zapis list&lt;zapis&gt; list как мне получить значение поля класса, например поле Number

21
Эксперт С++
4986 / 3093 / 456
Регистрация: 10.11.2010
Сообщений: 11,170
Записей в блоге: 10
17.02.2015, 23:21
Зачем вообще нужен класс Shape, если он пуст? Из-за этого и проблема, там нет, например переменной x2.
0
Заблокирован
17.02.2015, 23:40  [ТС]
Он понадобится в будущем, когда будем реализовывать свой собственный механизм отрисовки у каждого класса-наследника, а в Shape будут виртуальные функции.

Добавлено через 2 минуты
Но у класса Rect есть ведь эта переменная. Почему я не могу к ней обратиться? Ведь в векторе находятся по сути экземпляры класса Rect, а то, что вектор хранит Shape'ы, так что в этом плохого?
0
28 / 28 / 5
Регистрация: 23.04.2014
Сообщений: 130
17.02.2015, 23:57
Eru Iluvatar, во-первых, тут налицо попытка обратиться из внешнего кода к приватным данным. Не прокатит.
А во-вторых, ты можешь обращаться к потомкам через указатель на базовый класс. Чтобы это можно было делать, наследование должно быть public. В случае protected или private наследования внешний код "не видит" отношения наследования между этими классами и поэтому не позволит привести указатель на объект класса-наследника к указателю на объект класса-родителя.
Поэтому вектор лучше создать из указателей на Shape.
Я бы вообще использовал здесь шаблон Visitor, т.к. будет много однотипных действий над объектами разных классов-наследников от одного базового класса.
Пример обращения к наследнику через указатель:
C++
1
2
Shape *sh = new Rect();
sh->get_x1();
Добавлено через 15 минут
P.S. вообще ООП-наследование реализуется именно через public-наследование, а другие виды - это просто фишка C++. Чтобы не париться, постоянно указывая public, используй структуру вместо класса. Она по умолчанию наследуется с модификатором public.
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
17.02.2015, 23:57
Цитата Сообщение от Eru Iluvatar Посмотреть сообщение
И здесь у меня возникает ошибка 'class Shape' has no member named 'x2' и такое же сообщения о недоступности всех остальных координат. Почему возникает эта ошибка?
Потому что ваш класс Shape пуст. В нем нет никаких x2.

Цитата Сообщение от Eru Iluvatar Посмотреть сообщение
Как это исправить?
Пересмотреть свои взгляды на то, чем на самом деле является полиморфизм:

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
struct Shape
{
    virtual ~Shape(){} //<--- не забывайте про виртуальный диструктор
 
    virtual void draw(QPainter& painter) = 0; //<--- теперь система сможет отрисовать наследников 
      //ничего не зная об их устройстве
};
 
struct Rect: Shape
{
    Rect();
    //Построение по диагональным точкам
    Rect(int x1, int y1, int x2, int y2);
 
    virtual void draw(QPainter& painter)
    {
        int width = abs(shapes[i].x2 - shapes[i].x1);
        int height = abs(shapes[i].y2 - shapes[i].y1);
        painter.drawRect(shapes[i].x1, shapes[i].y1, width, height);
    }
 
private:
    int x1, y1; //Левый верхний угол
    int x2, y2; //Правый нижний угол
 
};
 
...
 
void MainWindow::paintEvent(QPaintEvent *p){
    qDebug() << "paintEvent";
    if(allowPainting == 1){
        qDebug() << "painting...";
        QPainter painter(this);
        for(int i = 0; i < shapes.size(); i++)
            shapes[i]->draw(painter);
    }
}
1
Заблокирован
18.02.2015, 00:17  [ТС]
В первый раз вижу, что структуры можно наследовать как классы и определять в них конструкторы и деструкторы.

Сделал такие изменения в своих классах, и получил ошибку: invalid abstract return type for member function 'Shape Vector::operator[](int)'

Хедер вектора:

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#ifndef VECTOR_H
#define VECTOR_H
#include "shapes.h"
 
class Vector
{
public:
    Vector();
     ~Vector ();
    void append(Shape *shape);
    Shape operator[](int i);
    int size()
    {
        return count;
    }
    void insert(int i, Shape *val);
private:
    Shape *array;
    int count, maxL;
    void extend(int x);
};
 
#endif // VECTOR_H
Реализация:

C++ (Qt)
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
#include "vector.h"
 
Vector::Vector()
{
    count=0;
    maxL=3;
    array=new Shape[maxL];
}
 
Vector::~Vector()
{
    delete[] array;
}
 
void Vector::append(Shape *value)
{
    if (count>=maxL)
        extend(5);
    array[count]=*value;
    count++;
}
 
Shape Vector::operator [](int i)
{
    if (i>=0 && i<count)
        return array[i];
    else
        return Shape();
}
 
void Vector::insert(int i, Shape *val)
{
    if(count>=maxL)
            extend(1);
            if(i > count)
            append(val);
            for (int j=count+1;j>i-1;j--)
            array[j]=array[j-1];
            array[i-1] = *val;
            count++;
}
 
void Vector::extend(int x)
{
 
        Shape *aa;
        aa=new Shape[maxL+x];
        for ( int j=0; j<=maxL; j++)
        {
            aa[j]=array[j];
            }
        maxL=maxL+x;
        delete[] array;
        array=aa;
 
}
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
18.02.2015, 00:43
Цитата Сообщение от Eru Iluvatar Посмотреть сообщение
В первый раз вижу, что структуры можно наследовать как классы и определять в них конструкторы и деструкторы.
У классов по умолчанию доступ private, а у struct - public.
В остальном принципиальной разницы нету.

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

Цитата Сообщение от Eru Iluvatar Посмотреть сообщение
invalid abstract return type for member function 'Shape Vector::operator[](int)'
смотрим сюда:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Vector
{
public:
    Vector();
     ~Vector ();
    void append(Shape *shape);
    Shape operator[](int i); //<---- упсссс
    int size()
    {
        return count;
    }
    void insert(int i, Shape *val);
private:
    Shape *array;
    int count, maxL;
    void extend(int x);
};
метод:
C++
1
Shape Vector::operator[](int i);
Делает копию элемента контейнера.

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

Вы уверены, что это именно то, что вам нужно?
Потому что обычно контейнеры не делают лишних копий.
Они возвращают ссылки на свои элементы:

C++
1
Shape& Vector::operator[](const size_t i);
И так, на всякий случай:
грамотные люди для хранения индексов или размеров используют беззнаковый тип данных size_t,
а вовсе не знаковый int.

Кроме того, хороший ход так же реализовать метод доступа к элементам контейнера в условиях,
когда сам контейнер константный:
C++
1
const Shape& Vector::operator[](const size_t i)const;
0
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9005 / 4706 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
18.02.2015, 00:51
Eru Iluvatar, я не увидел не единого виртуального метода.
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
#include <iostream>
#include <vector>
using namespace std;
//полиморфное наследование это если есть хотя бы один виртуальный метод
//иначе даже и пробовать достучаться не нужно
class Shap
{
public:
virtual void showData()const = 0;
~Shap(){}
};
 
class Circl : public Shap{
public:
    Circl()
    {
xc=0; yc=0; radius=0;
    }
    void showData()const
{
cout<< "xc= " << xc << " yc= " << yc << " radius= " << radius << endl;
}
int xc,yc, radius;
};
 
class Rectangl : public Shap{
public:
    Rectangl():xUpperLeft(0), xLowerRight(0), yUpperLeft(0), yLowerRight(0)
{
 
}
    void showData()const
{
cout<< "xUpperLeft= " << xUpperLeft << " yUpperLeft= " << yUpperLeft << "\
\nxLowerRight= " << xLowerRight << "yLowerRight= " << yLowerRight << endl;
}
int xUpperLeft, xLowerRight, yUpperLeft, yLowerRight;
};
 
int main()
{
Shap *rec = new Rectangl();
Shap *circ = new Circl();
vector<Shap*> shaps;
shaps.push_back(rec);
shaps.push_back (circ);
shaps[0]->showData();
cout<<endl;
shaps[1]->showData();
cout<<endl;
//не используя виртуальный метод достучаться до расширяющих данных
//можно преобразованием типа 
//что к чему преобразовывать можно выяснить используя RTTI (typeid в typeinfo.h)
//и потом так:
cout<<(dynamic_cast<Rectangl*>(shaps[0]))->xLowerRight;
//cout<<(dynamic_cast<Rectangl*>(shaps[1]))->xLowerRight;// тут поймаете исключение
//или даже как-то так)
Shap *rec2 = 0;//nullPtr
rec2 = dynamic_cast<Rectangl*>(shaps[1]);
if(rec2) rec2->showData();
else cout << "\nImpossible" << endl;
system("pause");
return 0;
}
0
Заблокирован
18.02.2015, 01:00  [ТС]
У меня сейчас классы написаны так:

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#ifndef RECTANGLE_H
#define RECTANGLE_H
#include <QPainter>
 
class Shape{
public:
    virtual ~Shape(){}
    virtual void draw(QPainter &p) = 0;
};
 
class Rect: public Shape{
private:
    int x1, y1; //Левый верхний угол
    int x2, y2; //Правый нижний угол
public:
    Rect();
    //Построение по диагональным точкам
    Rect(int x1, int y1, int x2, int y2);
};
 
#endif // RECTANGLE_H
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include "shapes.h"
 
Rect::Rect(){
    x1 = 0; y1 = 0;
    x2 = 0; y2 = 0;
}
 
Rect::Rect(int x1, int y1, int x2,int y2){
    this->x1 = x1;
    this->y1 = y1;
    this->x2 = x2;
    this->y2 = y2;
}
 
virtual void Rect::draw(QPainter &p){
    int width = abs(x2 - x1);
    int height = abs(y2 - y1);
    p.drawRect(x1, y1, width, height);
}
Во время добавления фигуры в вектор в строчке

C++ (Qt)
1
shapes.append(new Rect(angles.x1, angles.y2, angles.x2, angles.y2));
возникает ошибка: cannot allocate an object of abstract type 'Rect'

Из-за чего это? Я ведь вроде бы реализовал все виртуальные методы.
0
28 / 28 / 5
Регистрация: 23.04.2014
Сообщений: 130
18.02.2015, 01:08
Eru Iluvatar, в определении класса объяви метод draw без "= 0"
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
18.02.2015, 01:08
Цитата Сообщение от IGPIGP Посмотреть сообщение
class Shap
{
public:
virtual void showData()const = 0;
~Shap(){}
};
Пустой не виртуальный диструктор - плохая идея.

Цитата Сообщение от Eru Iluvatar Посмотреть сообщение
возникает ошибка: cannot allocate an object of abstract type 'Rect'
Из-за чего это? Я ведь вроде бы реализовал все виртуальные методы.
Не все. Ваш класс Rect не содержит декларации виртуального метода
C++
1
virtual void draw(QPainter &p);
А вот в спп файле:

C++
1
2
3
4
5
/*virtual*/ void Rect::draw(QPainter &p){ //<--- ключевое слово virtual нужно убрать
    int width = abs(x2 - x1);
    int height = abs(y2 - y1);
    p.drawRect(x1, y1, width, height);
}
0
28 / 28 / 5
Регистрация: 23.04.2014
Сообщений: 130
18.02.2015, 01:10
Цитата Сообщение от hoggy Посмотреть сообщение
C++
1
//<--- ключевое слово virtual нужно убрать
Вот это необязательно. Метод как был виртуальным, так и останется, это будет зависеть только от класса-родителя
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
18.02.2015, 01:11
Цитата Сообщение от GREGOR_812 Посмотреть сообщение
Eru Iluvatar, в определении класса объяви метод draw без "= 0"
Это называется "попытка спрятать симптомы, вместо того, что бы исправить причину".
Ему не поможет - будет ошибка линкера, который не сможет найти определение метода.

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

Добавлено через 54 секунды
Цитата Сообщение от GREGOR_812 Посмотреть сообщение
Вот это необязательно. Метод как был виртуальным, так и останется, это будет зависеть только от класса-родителя
Обязательно. При определении не должно быть ключевого слова virtual.
Таковы правила. Иначе - компилятор обидится, и отругает ошибками.
0
28 / 28 / 5
Регистрация: 23.04.2014
Сообщений: 130
18.02.2015, 01:12
Цитата Сообщение от hoggy Посмотреть сообщение
Это называется "попытка спрятать симптомы, вместо того, что бы исправить причину".
Ему не поможет - будет ошибка линкера, который не сможет найти определение метода.
Я про класс Rect говорил, если что. Определение метода у него есть. Но линкер его не ищет из-за этого нуля как раз, т.к. это нуль указывает ему на отсутствие определения

Добавлено через 44 секунды
Цитата Сообщение от hoggy Посмотреть сообщение
Обязательно. При определении не должно быть ключевого слова virtual.
Да, действительно, это моя ошибка) в определении virtual нельзя указывать, только в объявлении
0
Заблокирован
18.02.2015, 01:15  [ТС]
//<--- ключевое слово virtual нужно убрать
Сколько тонкостей.
Насчет декларации виртуального метода я думал, что это не обязательно, потому что он и так наследуется от базового класса.
Когда я сделал все эти изменения, возникла еще куча ошибок, но уже в классе вектор: там попытка создать экземпляр виртуального класса, и я даже не знаю, как теперь изменить всю логику этого класса, которая неплохо работала до того, как этот класс стал абстрактным.


C++ (Qt)
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
#include "vector.h"
 
Vector::Vector()
{
    count=0;
    maxL=3;
    array=new Shape[maxL];
}
 
Vector::~Vector()
{
    delete[] array;
}
 
void Vector::append(Shape *value)
{
    if (count>=maxL)
        extend(5);
    array[count]=*value;
    count++;
}
 
Shape& Vector::operator [](int i)
{
    if (i>=0 && i<count)
        return array[i];
    else
        return &Shape();
}
 
void Vector::insert(int i, Shape *val)
{
    if(count>=maxL)
            extend(1);
            if(i > count)
            append(val);
            for (int j=count+1;j>i-1;j--)
            array[j]=array[j-1];
            array[i-1] = *val;
            count++;
}
 
void Vector::extend(int x)
{
 
        Shape *aa;
        aa=new Shape[maxL+x];
        for ( int j=0; j<=maxL; j++)
        {
            aa[j]=array[j];
            }
        maxL=maxL+x;
        delete[] array;
        array=aa;
 
}
cannot allocate an object of abstract type 'Shape'
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
18.02.2015, 01:15
Цитата Сообщение от GREGOR_812 Посмотреть сообщение
Я про класс Rect говорил, если что.
Я понял. Я тоже именно о нем.

Цитата Сообщение от GREGOR_812 Посмотреть сообщение
Определение метода у него есть.
При определении виртуальной функции-члена,
ключевое слово virtual должно быть опущено.

Цитата Сообщение от GREGOR_812 Посмотреть сообщение
Но линкер его не ищет из-за этого нуля как раз, т.к. это нуль указывает ему на отсутствие определения
В корне не верная мысль.

У ТС ошибка компилятора, а не линкера. До линкера дело вообще не дошло.
А компилятор ругается, из-за того, что в классе отсутствует декларация прототипа функции-члена.

Определение у него есть. А вот объявления нету.
0
Заблокирован
18.02.2015, 01:17  [ТС]
Ошибка в строке

C++ (Qt)
1
return &Shape();
0
28 / 28 / 5
Регистрация: 23.04.2014
Сообщений: 130
18.02.2015, 01:19
hoggy, по-моему, Вы меня неправильно поняли. У автора в базовом классе объявлен абстрактный метод, а в наследнике нет его объявления без "= 0", т.е. он остаётся абстрактным. Нужно не только добавить определение, но и объявить метод не абстрактным. Я это хотел сказать
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
18.02.2015, 01:21
Цитата Сообщение от Eru Iluvatar Посмотреть сообщение
Shape& Vector::operator [](int i)
{
if (i>=0 && i<count)
return array[i];
else
return Shape(); //<--- boomb!!!!
}
По идее у вас не должно такое скомпилироваться.
1. Нельзя возвращать ссылку на временный объект.
2. Нельзя цеплять временные объекты по ссылкам на изменяемые объекты.


C++
1
2
3
4
5
6
7
Shape& Vector::operator [](const size_t i)
{
    if (i < count)         //<--- count должен быть беззнаковым
        return array[i];
    else
        throw std::out_of_range("out of range"); //<--- если индекс корявый, кидаем исключение
}
Добавлено через 1 минуту
Цитата Сообщение от GREGOR_812 Посмотреть сообщение
hoggy, по-моему, Вы меня неправильно поняли. У автора в базовом классе объявлен абстрактный метод, а в наследнике нет его объявления без "= 0", т.е. он остаётся абстрактным. Нужно не только добавить определение, но и объявить метод не абстрактным. Я это хотел сказать
Ааа... ну это да.
В наследнике нолик указывать не нужно.
0
Заблокирован
18.02.2015, 01:24  [ТС]
'out_of_range' is not a member of 'std'

Теперь та же самая ошибка создания объекта при создании массивов, как здесь:

C++ (Qt)
1
array=new Shape[maxL];
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
18.02.2015, 01:24
Помогаю со студенческими работами здесь

Доступ к полям MainActivity
Добрый день, что-то не могу сообразить, как получить доступ к полям MainActivity из другого класса ? обычно доступ к полям через объект...

Доступ к полям записи
Какое с зарегистрированных слов используют для доступа к полям записи?

Доступ к полям datagridview
Здравствуйте, у меня на форме кнопка и датагрид....После запуска программы таблица заполняется значениями из xml файла. Как по нажатию...

Доступ к protected полям
Добрый день! Очень не часто пишу что-то на C++ и вот такой момент настал :) Существует некий абстрактный класс содержащий указатель на...

Доступ к полям формы
прошу помощи уважаемого сообщества, создал БД все работает, все пользуются, всё нормально... было... но нашлась &quot;паршивая...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка. Рецензия / Мнение Это мой обзор планшета X220 с точки зрения школьника. Недавно я решила попытаться уменьшить свой. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД 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
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru