Войти
ФлеймФорумПрограммирование

Общие вопросы по программированию (455 стр)

Страницы: 1454 455 456 457562 Следующая »
#6810
(Правка: 22:04) 21:55, 23 авг 2022

Aroch
> При конструкторах виртуальный метод не вызвать
Ещё раз повторюсь - виртуальный метод вызывается без проблем. Проблема может заключаться в том, что сам объект во время работы конструктора - принадлежит классу именно этого конструктора, и виртуальный метод будет вызван соответствующий. Если у нас есть классы Base и Derived: Base, и мы инициализируем экземпляр Derived d - пока будет выполняться конструктор базового класса, typeof(d) == typeid(Base). И только после того, как базовый конструктор завершит работу, отработают конструкторы полей дерайведа, и сам конструктор Derived::Derived войдёт в свой скоуп - только тогда виртуальная таблица объекта обновится, и он станет typeof(d) == typeid(Base).

struct Typed {
    virtual char const* getType() = 0;
};

void printTypeOf(char const* where, Typed* obj) {
    // самый настоящий обычный виртуальный вызов
    // можем эту функцию вообще скомпилировать отдельно и вынести в длл
    printf("In %s, the type of %#18llx is %s\n", where, (intptr_t)obj, obj->getType());
}

struct Base: Typed {
    virtual char const* getType() override {
        return "Base";
    }

    Base() {
        printTypeOf("Base::Base", this);
        // всегда будет печатать
        //> In Base::Base, the type of 0xbebebebe is Base
    }

    ~Base() {
        printTypeOf("Base::~Base", this);
        // всегда будет печатать
        //> In Base::~Base, the type of 0xbebebebe is Base
    }
};

struct Derived: Base {
    virtual char const* getType() override {
        return "Derived";
    }

    Derived() {
        printTypeOf("Derived::Derived", this);
        // всегда будет печатать
        //> In Derived::Derived, the type of 0xbebebebe is Derived
    }

    ~Derived() {
        printTypeOf("Derived::~Derived", this);
        // всегда будет печатать
        //> In Derived::~Derived, the type of 0xbebebebe is Derived
    }
};

Если бы виртуальный метод было "не вызвать" - то вызов printTypeOf, который содержит вызов к виртуальной функции, закрашил бы программу. Но это не так - он отрабатывает, и у него даже есть чётко определённое поведение (без УБ).

#6811
22:06, 23 авг 2022

Ну то есть особенность вызова виртуальных функций в конструкторах и деструкторах (а также в любых методах, которые вызваны из них) кратко можно описать так:

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

#6812
22:46, 23 авг 2022

Имбирная Ведьмочка
> Если бы виртуальный метод было "не вызвать" - то вызов printTypeOf, который
> содержит вызов к виртуальной функции, закрашил бы программу. Но это не так - он
> отрабатывает, и у него даже есть чётко определённое поведение (без УБ).
ты же сам видишь как он обрабатывает, что вызывается функция класса который был создан, а не та которого должны создать. С точки зрения класса который уже успел создаться если у тебя более длинная цепочка наследования, то да произошел вызов виртуальной функции. Только дальше она не пойдет. Как бы тут нет ничего противоречивого с тем что ранее было сказано.

#6813
22:51, 23 авг 2022

Dmitry_Milk
> никогда с этим не сталкивался...
для интерфейсов там вообще "pure virtual function call" получится
это хорошо что не сталкивался, наследование зло

#6814
23:06, 23 авг 2022

nes
> std::array
На мой взгляд какой-то недоделанный класс получился.

#6815
23:16, 23 авг 2022

#!
> для интерфейсов там вообще "pure virtual function call" получится

Хыы, да, шляпа. И ведь компилятор даже не сообразил, что чистая виртуальная функция вызывается в деструкторе опосредованно через intermediate (если напрямую вызовать - при компиляции сообразил).

https://rextester.com/OCG64855

#6816
23:16, 23 авг 2022

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

#6817
0:02, 24 авг 2022

std::vector и std::string в игровом движке - стоит использовать или писать велосипед, подводные, аргументы?

#6818
0:05, 24 авг 2022

Aroch
> удобства при использовании имеются.
Удобно было бы, если бы это имело интерфейс вектора с постоянным капасити.

#6819
0:31, 24 авг 2022

0xBADCODE
А движок свой или готовый? Если свой, то вектор и строка тоже должны быть своими. Со своим аллокатором.

#6820
(Правка: 0:56) 0:55, 24 авг 2022

1 frag / 2 deaths
> 0xBADCODE
> А движок свой или готовый?
Пишу свой.
>Если свой, то вектор и строка >тоже должны быть
> своими. Со своим аллокатором.
Почему?

#6821
6:07, 24 авг 2022

0xBADCODE
> Удобно было бы, если бы это имело интерфейс вектора с постоянным капасити.
а метода beep() там не должно быть? Ну чтобы удобно было, сравнил размер и сразу beep() под рукой в случае чего, не?

#6822
8:12, 24 авг 2022

Aroch
> а метода beep() там не должно быть?
Достаточно эксепшна. Мне приходилось заводить отдельную переменную для учета реально хранящегося в std::array числа элементов, хотя до знакомства с ним я полагал, что можно будет просто воспользоваться push_back() и size().

#6823
9:16, 24 авг 2022

Очередной глупый вопрос, как очистить массив

struct TilesCell
{
  TilesCell()
  {
    memset(tiles, 0, SizeMapZ * SizeMap* SizeMap);
  }

  Tile* tiles[SizeMapZ][SizeMap][SizeMap];
};

Не работает - какой-то элемент не обнуляется (вылетает по 0xFFFFFFF - что в дебаге как признак что элемент не занулен)

#6824
9:22, 24 авг 2022

war_zes
>
> memset(tiles, 0, SizeMapZ * SizeMap* SizeMap);
memset требует размер в байтах, а не количество элементов в массиве, разве нет?

Страницы: 1454 455 456 457562 Следующая »
ФлеймФорумПрограммирование