crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

Litkevich Yuriy
  опции профиля:
сообщение 17.8.2010, 12:57
Сообщение #1


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Никак не могу въехать в виртуальный деструктор.
Есть некая программа написанная с использованием Qt, работает стабильно. При развитии программы, она может падать в некий момент времени, обычно при взаимодействии с пользовательским интерфейсом. Но чаще возникает авария при завершении работы.
Эту ситуацию можно пердотвратить в ведя в один из классов пустой, ничего не делающий, виртуальный деструктор.

Речь идёт о наследнике либо QObject, либо QWidget.

Может кто-нибудь объяснить, как может влиять создание руками виртуального деструктора, при условии, что его тело пустое?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
5 страниц V   1 2 3 > »   
Начать новую тему
Ответов (1 - 41)
BRE
  опции профиля:
сообщение 17.8.2010, 13:04
Сообщение #2


Профессионал
*****

Группа: Участник
Сообщений: 1112
Регистрация: 6.3.2009
Из: Ростов-на-Дону
Пользователь №: 591

Спасибо сказали: 264 раз(а)




Репутация:   44  


Ситуация вообще странная.
Насколько я помню, виртуальный деструктор вводиться еще в QObject, т.е. все остальные деструкторы в наследниках (включая QWidget) по умолчанию виртуальные.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 17.8.2010, 13:14
Сообщение #3


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Цитата(BRE @ 17.8.2010, 17:04) *
Насколько я помню, виртуальный деструктор вводиться еще в QObject,
да, но вот Креатор, например, генерит файлы классов всегда с явно указанным деструктором, если базовый класс является QObject/QWidget.

Я просто решил сделать по аналогии, в одной из программ. которая падает при закрытии. И программа перестала падать.

Как это работает я не пойму.

Если я правильно понимаю, то должно работать так. Дано:
class QObject
{
              QObject();
  virtual ~QObject();
};


class MyObject : public QObject
{
              MyObject();

}
где-то далее в коде:
QObject  *o = new MyObject();
delete o; // <--------
в выделенной строке должен вызываться деструктор класса MyObject

или я не прав?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
BRE
  опции профиля:
сообщение 17.8.2010, 13:19
Сообщение #4


Профессионал
*****

Группа: Участник
Сообщений: 1112
Регистрация: 6.3.2009
Из: Ростов-на-Дону
Пользователь №: 591

Спасибо сказали: 264 раз(а)




Репутация:   44  


Прав.
Вызовется деструтор MyObject, а потом QObject.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 17.8.2010, 13:27
Сообщение #5


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


и ещё, при отладке в Креаторе увидел что в консоль приложения печатается такая строка:
Lowest section in J:\WINDOWS\system32\xpsp2res.dll is .rsrc at 00011000

если же запускаю программу в командной строке виндовоза, то такой надписи нет. Это может предвещать что-то плохое?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 17.8.2010, 13:36
Сообщение #6


фрилансер
******

Группа: Участник
Сообщений: 2943
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


Litkevich Yuriy, а когда запущено на отладку без точек останова - не видно, где падение произошло ? Обычно стек вызовов можно раскрутить до своего кода
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 17.8.2010, 13:42
Сообщение #7


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Цитата(Алексей1153 @ 17.8.2010, 17:36) *
Обычно стек вызовов можно раскрутить до своего кода
да вот GDB сволочной отладчик, когда нужно найти проблему, он руками разводит, говорит "Может стек корупт, а?"


Но походу тут лажа очередная с qmake'ом. Прибил всю сборку, собрал начисто, всё работает. Даже намёка на падение нет, что без деструктора, что с явно созданным.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
DEADHUNT
  опции профиля:
сообщение 17.8.2010, 14:10
Сообщение #8


Активный участник
***

Группа: Участник
Сообщений: 430
Регистрация: 15.4.2009
Пользователь №: 686

Спасибо сказали: 26 раз(а)




Репутация:   2  


добавляя виртуальный деструктор получаем:
1) полиморфный класс, т.е. возможность использования dynamic_cast, typeid, ...
2) объекты можно удалять через указатель на базовый класс, при этом будет вызываться деструктор производного класса и корректно свобождается память.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Влад
  опции профиля:
сообщение 17.8.2010, 15:18
Сообщение #9


Участник
**

Группа: Участник
Сообщений: 146
Регистрация: 20.3.2009
Из: Санкт-Петербург
Пользователь №: 627

Спасибо сказали: 46 раз(а)




Репутация:   8  


Ежли мой склероз мне не изменяет, еще Джефф Элджер в своей "С++ Библиотека программиста" советовал: делайте деструктор всегда виртуальным, за исключением лишь тех случаев, когда есть чрезвычайно веские основания поступить иначе.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 17.8.2010, 15:20
Сообщение #10


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Цитата(DEADHUNT @ 17.8.2010, 18:10) *
добавляя виртуальный деструктор получаем:
речь идёт о деструкторе базового класса или наследника?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
DEADHUNT
  опции профиля:
сообщение 17.8.2010, 15:39
Сообщение #11


Активный участник
***

Группа: Участник
Сообщений: 430
Регистрация: 15.4.2009
Пользователь №: 686

Спасибо сказали: 26 раз(а)




Репутация:   2  


Цитата(Litkevich Yuriy @ 17.8.2010, 16:20) *
речь идёт о деструкторе базового класса или наследника?

class A {
    virtual ~A() { }
};

класс имеет виртуальный деструктор, т.е. в классе есть хотя бы один виртуальный метод, таким образом компилятор считает данный класс полиморфным, и обращается с ним иначе чем с обычными классами(как описано выше).
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 17.8.2010, 16:37
Сообщение #12


фрилансер
******

Группа: Участник
Сообщений: 2943
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


Цитата(Влад @ 17.8.2010, 18:18) *
за исключением лишь тех случаев, когда есть чрезвычайно веские основания поступить иначе

о, я даже прошёлся по этим граблям разок ) Если интересно, могу вспомнить
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 17.8.2010, 16:38
Сообщение #13


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Цитата(DEADHUNT @ 17.8.2010, 19:39) *
класс имеет виртуальный деструктор
ну это-то понятно, это я в первых постах написал.
Мне не понятно, может ли влиять явное создание пустого деструктора у наследника QObject (или иного класса, с виртуальным деструктором).
На мой взгляд нет.


Но похоже это какая-то кривость Креатора. Любое изменение в коде (в заголовочниках) сейчас опять выливается в аврию. Если же компилю в консоли или в PN-2, то всё нормально.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
kwisp
  опции профиля:
сообщение 17.8.2010, 17:07
Сообщение #14


астарожна ынтжинэр
*****

Группа: Участник
Сообщений: 1404
Регистрация: 26.11.2008
Из: ТаганрогРодинаЧехова
Пользователь №: 435

Спасибо сказали: 113 раз(а)




Репутация:   23  


лишний повод(причина) не использовать креатор.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Iron Bug
  опции профиля:
сообщение 17.8.2010, 17:53
Сообщение #15


Профессионал
*****

Группа: Модератор
Сообщений: 1611
Регистрация: 6.2.2009
Из: Yekaterinburg
Пользователь №: 533

Спасибо сказали: 219 раз(а)




Репутация:   12  


Цитата(Litkevich Yuriy @ 17.8.2010, 19:38) *
Мне не понятно, может ли влиять явное создание пустого деструктора у наследника QObject (или иного класса, с виртуальным деструктором).
На мой взгляд нет.


однозначно нет.
скорее всего, ошибка в потоках, либо в оставшихся "висящими" объектах ядра. проверяй, все ли ресурсы освобождаются корректно, правильно ли завершаются потоки, нет ли "подвисших" линков на несуществующие переменные после закрытия основного потока.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 17.8.2010, 18:41
Сообщение #16


фрилансер
******

Группа: Участник
Сообщений: 2943
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


и ещё
... вызываются ли виртуальные функции в деструкторе (низя)
... производится ли где-то явное приведение типа с последующим изменением начала объекта (бьётся таблица виртуальных функций)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
BRE
  опции профиля:
сообщение 17.8.2010, 19:00
Сообщение #17


Профессионал
*****

Группа: Участник
Сообщений: 1112
Регистрация: 6.3.2009
Из: Ростов-на-Дону
Пользователь №: 591

Спасибо сказали: 264 раз(а)




Репутация:   44  


Цитата(Алексей1153 @ 17.8.2010, 19:41) *
... вызываются ли виртуальные функции в деструкторе (низя)

Почему нельзя?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
kwisp
  опции профиля:
сообщение 17.8.2010, 19:08
Сообщение #18


астарожна ынтжинэр
*****

Группа: Участник
Сообщений: 1404
Регистрация: 26.11.2008
Из: ТаганрогРодинаЧехова
Пользователь №: 435

Спасибо сказали: 113 раз(а)




Репутация:   23  


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

по моему логично

если диструктор не виртуальный а в нем виртуальные функции то эти вирту функции напросто обратятся уже к удаленным полям производного объекта.
порядок вызова деструкторов обратный то
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 17.8.2010, 19:11
Сообщение #19


фрилансер
******

Группа: Участник
Сообщений: 2943
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


Вроде нельзя, потому что виртуальная таблица уже порушена. Будут вызываться функции данного объекта, а не потомков
А как там в стандарте ?

Надо будет эксперимент поставить, но щас у меня мысль в другом русле, пока не могу )

Сообщение отредактировал Алексей1153 - 17.8.2010, 19:13
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
BRE
  опции профиля:
сообщение 17.8.2010, 19:20
Сообщение #20


Профессионал
*****

Группа: Участник
Сообщений: 1112
Регистрация: 6.3.2009
Из: Ростов-на-Дону
Пользователь №: 591

Спасибо сказали: 264 раз(а)




Репутация:   44  


На сколько я помню, при удалении объекта с виртуальным деструктором, будет вызван деструктор из его vtbl. После его отработки, vtbl будет переключена на таблицу базового класса и будет вызван его деструктор и т.д. Даже если ты будешь удалять объект по указателю на его базовый класс. В этом и смысл.
А вот с конструкторами такое не пройдет, они не могут быть виртуальными. Поэтому, в конструкторе будет вызван виртуальный метод того класса, конструктор которого в данный момент работает, даже если в производном классе он переопределен.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 17.8.2010, 19:24
Сообщение #21


фрилансер
******

Группа: Участник
Сообщений: 2943
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


нет, речь не про виртуальный деструктор, а про явный вызов виртуальных функций из деструктора предка
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
BRE
  опции профиля:
сообщение 17.8.2010, 19:27
Сообщение #22


Профессионал
*****

Группа: Участник
Сообщений: 1112
Регистрация: 6.3.2009
Из: Ростов-на-Дону
Пользователь №: 591

Спасибо сказали: 264 раз(а)




Репутация:   44  


Ты про чисто виртуальные функции или просто виртуальные?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 17.8.2010, 19:51
Сообщение #23


фрилансер
******

Группа: Участник
Сообщений: 2943
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


Щас сделаю тест, самому охота вспомнить )

хм, выяснилась интересная вещь. Ни Креатор, ни Студия (№6, №9) просто не позволяют так сделать ещё на уровне линковки

class A
{
public:
    virtual void F()=0;

    void CallF()
    {
        F();
    }

    virtual ~A()
    {
        F();//<<<<< на это ругань
    }
};

class B:public A
{
public:
    void F()
    {
        int iii=1;
    }

    void CallF()
    {
        F();
    }

    ~B()
    {
        F();
    }
};


void main()
{
    B b;
    b.CallF();
}



Цитата
unresolved external symbol "public: virtual void __thiscall A::F(void)" (?F@A@@UAEXXZ)


Цитата
undefined reference to `A::F()'


А ведь я помню, нарвался как то на подобное, но не могу вспомнить, как именно

Сообщение отредактировал Алексей1153 - 17.8.2010, 19:54
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Iron Bug
  опции профиля:
сообщение 17.8.2010, 20:21
Сообщение #24


Профессионал
*****

Группа: Модератор
Сообщений: 1611
Регистрация: 6.2.2009
Из: Yekaterinburg
Пользователь №: 533

Спасибо сказали: 219 раз(а)




Репутация:   12  


Цитата(BRE @ 17.8.2010, 22:20) *
На сколько я помню, при удалении объекта с виртуальным деструктором, будет вызван деструктор из его vtbl. После его отработки, vtbl будет переключена на таблицу базового класса и будет вызван его деструктор и т.д. Даже если ты будешь удалять объект по указателю на его базовый класс. В этом и смысл.
А вот с конструкторами такое не пройдет, они не могут быть виртуальными. Поэтому, в конструкторе будет вызван виртуальный метод того класса, конструктор которого в данный момент работает, даже если в производном классе он переопределен.

абсолютно верно. именно так и будет.
если в классе виртуальная функция определена, то она может быть вызвана в деструкторе этого класса и в деструкторах классов-наследников, если вдруг потребуется. для каждого класса могут использоваться его функции и функции прародителей. для деструктора нет ограничений. они есть только для конструктора - так как в момент создания элемента виртуальной таблицы и указателя this просто ещё нет.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 18.8.2010, 4:26
Сообщение #25


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Цитата(Алексей1153 @ 17.8.2010, 22:41) *
... вызываются ли виртуальные функции в деструкторе (низя)
нет, у меня именно пустой деструктор (мне нечего было подчищать при завершении работы класса), а насчёт того, что нельзя, я тоже краем уха где-то слышал.
Цитата(Алексей1153 @ 17.8.2010, 22:41) *
... производится ли где-то явное приведение типа с последующим изменением начала объекта
вот это не понял, что значит с изменением начала объекта?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 18.8.2010, 6:50
Сообщение #26


фрилансер
******

Группа: Участник
Сообщений: 2943
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


Цитата(Litkevich Yuriy @ 18.8.2010, 7:26) *
а насчёт того, что нельзя, я тоже краем уха где-то слышал.

поскольку точно не могу факт привести, не буду придумывать :) Лучше всегда поставить эксперимент на месте и проверить в отладчике.

Цитата(Litkevich Yuriy @ 18.8.2010, 7:26) *
вот это не понял, что значит с изменением начала объекта?


например
Раскрывающийся текст
    //общий вид сообщения из 4 байтов
    struct SomeMessage
    {
        //флаги, общие для всех сообщений
        BYTE b1:1;
        BYTE b2:1;
        BYTE b3:1;
        BYTE b4:1;
        BYTE b5:1;
        BYTE b6:1;
        BYTE b7:1;
        BYTE b8:1;

        //код сообщения
        BYTE m_Code;

        //разные данные - зависят от m_Code
        WORD m_SomeData;

        virtual ~SomeMessage()
        {
            m_Code=0;
        }

        void FillMe(DWORD dwdRawData)
        {
            //грабля №1 - размер *this равен 8 байтов, а не 4, как ожидается
            //поэтому проверка вернёт false
            if(sizeof(*this)==sizeof(dwdRawData))
            {
                //грабля №2 - запись произошлы бы не в тело структуры, а 
                //ровнёхонько в виртуальную таблицу
                *((DWORD*)this)=dwdRawData;
            }
        }
    };


void main()
{
    DWORD dwd=0x110022FF;
    SomeMessage m;
    m.FillMe(dwd);
    //виртуальная таблица была бы испорчена, если бы не проверка №1 в функции

}


Сообщение отредактировал Алексей1153 - 18.8.2010, 6:52
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
kwisp
  опции профиля:
сообщение 18.8.2010, 9:43
Сообщение #27


астарожна ынтжинэр
*****

Группа: Участник
Сообщений: 1404
Регистрация: 26.11.2008
Из: ТаганрогРодинаЧехова
Пользователь №: 435

Спасибо сказали: 113 раз(а)




Репутация:   23  


Цитата(Алексей1153 @ 17.8.2010, 20:51) *
хм, выяснилась интересная вещь. Ни Креатор, ни Студия (№6, №9) просто не позволяют так сделать ещё на уровне линковки

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

# include <iostream>
# include <string>

class Parent 
{
public:
    /*virtual*/ ~Parent()
    {
        std::cout << __PRETTY_FUNCTION__ << '\n';
        printData();
    }
    virtual void printData()
    {
        std::cout << __PRETTY_FUNCTION__ << '\n';
    }
};

class Child : public Parent
{
public:
    Child()
    {
        std::cout << __PRETTY_FUNCTION__ << '\n';
        m_data = new std::string("hello world");
    }
    void printData()
    {
        std::cout << __PRETTY_FUNCTION__ << '\n';
        std::cout << *m_data << '\n';
    }
    ~Child()
    {
        std::cout << __PRETTY_FUNCTION__ << '\n';
        delete m_data;
    }

private:
    std::string* m_data;

};

int main()
{
    Child* child = new Child;
    static_cast<Parent*>(child)->printData();
    delete child;
    return 0;
}



./a.out 
Child::Child()
virtual void Child::printData()
hello world
Child::~Child()
Parent::~Parent()
virtual void Parent::printData()
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 18.8.2010, 10:11
Сообщение #28


фрилансер
******

Группа: Участник
Сообщений: 2943
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


Цитата(Алексей1153 @ 17.8.2010, 22:11) *
функции данного объекта, а не потомков


kwisp, вообще-то, я про потомков говорил ) Ведь назначение виртуальных функций - вызывать методы потомков

Цитата(kwisp @ 18.8.2010, 12:43) *
вызов чисто виртуальной функции.

такой вызов не запрещён вроде :)
Потому что абстрактный объект создать нельзя, а потомки должны обязательно переопределить виртуалки

Сообщение отредактировал Алексей1153 - 18.8.2010, 10:13
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
kwisp
  опции профиля:
сообщение 18.8.2010, 11:16
Сообщение #29


астарожна ынтжинэр
*****

Группа: Участник
Сообщений: 1404
Регистрация: 26.11.2008
Из: ТаганрогРодинаЧехова
Пользователь №: 435

Спасибо сказали: 113 раз(а)




Репутация:   23  


Цитата(Алексей1153 @ 17.8.2010, 20:11) *
Будут вызываться функции данного объекта, а не потомков

вот

Цитата(Алексей1153 @ 18.8.2010, 11:11) *
такой вызов не запрещён вроде :)

да ну не верится.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 18.8.2010, 12:20
Сообщение #30


фрилансер
******

Группа: Участник
Сообщений: 2943
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


что тут верить то :) Проверить, и всё
class A
{
public:
    virtual void F()=0;

    void Call_F()
    {
        F();
    }

    virtual ~A()
    {
    }

};

class B:public A
{
public:
    void F()
    {

    }
};

main()
{

    A* pa =new B;

    pa->F();
    pa->Call_F();
    delete pa;
    pa=0;
}


Сообщение отредактировал Алексей1153 - 18.8.2010, 12:22
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
kwisp
  опции профиля:
сообщение 18.8.2010, 13:41
Сообщение #31


астарожна ынтжинэр
*****

Группа: Участник
Сообщений: 1404
Регистрация: 26.11.2008
Из: ТаганрогРодинаЧехова
Пользователь №: 435

Спасибо сказали: 113 раз(а)




Репутация:   23  


Алексей1153,
хитрец ты вызываешь не чисто виртуальную функцию а переорпеделенную.
рассмотри пример у меня в посте выше и вывод на консоль.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
DEADHUNT
  опции профиля:
сообщение 18.8.2010, 13:41
Сообщение #32


Активный участник
***

Группа: Участник
Сообщений: 430
Регистрация: 15.4.2009
Пользователь №: 686

Спасибо сказали: 26 раз(а)




Репутация:   2  


Цитата(Алексей1153 @ 18.8.2010, 13:20) *
что тут верить то :) Проверить, и всё

код собирается без ошибок.
а в конце 10.4 (Abstract Classes) написано:
Цитата
Member functions can be called from a constructor (or destructor) of an abstract class; the effect of making a
virtual call (10.3) to a pure virtual function directly or indirectly for the object being created (or destroyed)
from such a constructor (or destructor) is undefined.

в таких случаях лучше реализовывать чисто виртуальную функцию:
class A {
public:
    virtual void foo() = 0;
};

void A::foo()
{
}

Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 18.8.2010, 13:57
Сообщение #33


фрилансер
******

Группа: Участник
Сообщений: 2943
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


Цитата(kwisp @ 18.8.2010, 16:41) *
хитрец ты вызываешь не чисто виртуальную функцию а переорпеделенную.

прошагай отладчиком - никакой хитрости :) Или я просто не понял, что ты имел в виду под "вызов чистых виртуальных функций". Ведь в классе A - это и есть есть чистая :)

Сообщение отредактировал Алексей1153 - 18.8.2010, 13:58
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
DEADHUNT
  опции профиля:
сообщение 18.8.2010, 14:02
Сообщение #34


Активный участник
***

Группа: Участник
Сообщений: 430
Регистрация: 15.4.2009
Пользователь №: 686

Спасибо сказали: 26 раз(а)




Репутация:   2  


Цитата(Алексей1153 @ 18.8.2010, 14:57) *
Или я просто не понял, что ты имел в виду под "вызов чистых виртуальных функций".

struct A {
virtual void foo() = 0;
};

struct B : public A {

void foo()
{
    A::foo(); // <-
}

};


Сообщение отредактировал DEADHUNT - 18.8.2010, 14:03
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Iron Bug
  опции профиля:
сообщение 18.8.2010, 15:03
Сообщение #35


Профессионал
*****

Группа: Модератор
Сообщений: 1611
Регистрация: 6.2.2009
Из: Yekaterinburg
Пользователь №: 533

Спасибо сказали: 219 раз(а)




Репутация:   12  


Цитата(Litkevich Yuriy @ 17.8.2010, 15:57) *
Может кто-нибудь объяснить, как может влиять создание руками виртуального деструктора, при условии, что его тело пустое?

я уже писала: никак не влияет. просто лишний вызов или перераспределение кода при очередной компиляции скрывает ошибку потоков или затирания памяти.
от пустого деструктора абсолютно ничего не прибавляется, виртуальный он или не виртуальный.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 18.8.2010, 19:12
Сообщение #36


фрилансер
******

Группа: Участник
Сообщений: 2943
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


DEADHUNT, понятно )

А я то понял, что про именно из A вызов говорилось

Сообщение отредактировал Алексей1153 - 18.8.2010, 19:13
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 19.8.2010, 8:51
Сообщение #37


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


вобщем шутки RunTime продолжаются.

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

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

Не уж-то на CMake придётся переходить? Так не охота что-то изучать на середине проекта.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 19.8.2010, 12:43
Сообщение #38


фрилансер
******

Группа: Участник
Сообщений: 2943
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


Litkevich Yuriy, а у тебя нигде директива не используется такая?
#pragma pack


upd
(всё, вопрос неактуален )) Внимательнее прочитал пост Юрия и понял, что это ни при чём)

Сообщение отредактировал Алексей1153 - 19.8.2010, 12:44
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
DEADHUNT
  опции профиля:
сообщение 19.8.2010, 14:23
Сообщение #39


Активный участник
***

Группа: Участник
Сообщений: 430
Регистрация: 15.4.2009
Пользователь №: 686

Спасибо сказали: 26 раз(а)




Репутация:   2  


Цитата(Litkevich Yuriy @ 19.8.2010, 9:51) *
Не уж-то на CMake придётся переходить? Так не охота что-то изучать на середине проекта.

а все вызовы дополнительных утилит(moc, uic, etc.) в ручную прописывать?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
BRE
  опции профиля:
сообщение 19.8.2010, 14:25
Сообщение #40


Профессионал
*****

Группа: Участник
Сообщений: 1112
Регистрация: 6.3.2009
Из: Ростов-на-Дону
Пользователь №: 591

Спасибо сказали: 264 раз(а)




Репутация:   44  


Цитата(DEADHUNT @ 19.8.2010, 15:23) *
а все вызовы дополнительных утилит(moc, uic, etc.) в ручную прописывать?

Зачем? CMake это все умеет и даже намного больше. :)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
DEADHUNT
  опции профиля:
сообщение 19.8.2010, 14:36
Сообщение #41


Активный участник
***

Группа: Участник
Сообщений: 430
Регистрация: 15.4.2009
Пользователь №: 686

Спасибо сказали: 26 раз(а)




Репутация:   2  


вот нашёл пример: http://www.devexp.ru/2010/01/cmake-i-qt/ там макросы для этого есть.
на самом деле зачем постоянно использовать qmake, ведь проект который использует Qt != Qt проект.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 19.8.2010, 15:51
Сообщение #42


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Цитата(DEADHUNT @ 19.8.2010, 18:23) *
а все вызовы дополнительных утилит(moc, uic, etc.) в ручную прописывать?
можно и так сказать, т.к. отдельные списки создавать надо
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

5 страниц V   1 2 3 > » 
Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0


RSS Рейтинг@Mail.ru Текстовая версия Сейчас: 24.5.2025, 11:16