Правильное размещение и освобождение подкласса QCPGraph - PullRequest
0 голосов
/ 31 августа 2018

Я использую QCustomPlot и подклассифицировал QCPGraph, чтобы получить нарисованный график.

class QCPDrawableGraph : public QCPGraph {
    Q_OBJECT
public:
    QCPDrawableGraph(QCPAxis* x, QCPAxis* y) : QCPGraph(x,y) {
        //do stuff
    }
    virtual ~QCPDrawabelGraph() {} // necessary?
    //class stuff
};

Обычно можно создать новые графики к

QCustomPlot plot(parent); //where parent is the parent widget of the gui
QCPGraph* gr = plot->addGraph(); // in case of QCPGraphs or
QCPGraph* gr = new QCPGraph(plot->xAxis,plot->yAxis); // as with all other QCPAbstractPlottables

Буду ли я использовать свой собственный класс, как

QCPDrawableGraph* dgr = new QCPDrawableGraph(plot->xAxis,plot->yAxis); //?

Деструктор QCustomPlot по-прежнему заботится о перераспределении в конце?

1 Ответ

0 голосов
/ 31 августа 2018

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

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

Это касается и ОП QCPDrawableGraph.

Это явно упоминается в документе. из QPCGraph ( Документация конструктора и деструктора ):

Созданный QCPGraph автоматически регистрируется с экземпляром QCustomPlot , выведенным из keyAxis . Этот QCustomPlot становится владельцем QCPGraph , поэтому не удаляйте его вручную, а используйте вместо него QCustomPlot :: removePlottable () .

Как конструктор ОП QCPDrawableGraph

QCPDrawableGraph(QCPAxis* x, QCPAxis* y) : QCPGraph(x,y) {
    //do stuff
}

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


По поводу уничтожения небольшой образец:

#include <iostream>

struct Base {
  virtual ~Base() { std::cout << "Base::~Base()\n"; }
};

struct Derived: Base {
  ~Derived() { std::cout << "Derived::~Derived()\n"; }
};

int main()
{
  Base *p = new Derived();
  delete p;
  return 0;
}

Выход:

Derived::~Derived()
Base::~Base()

Демонстрация в реальном времени на ideone

Примечания:

  1. Деструктор ~Derived() равен virtual даже без ключевого слова virtual, поскольку деструктор его базового класса Base равен.

  2. Деструктор ~Derived() вызывается первым, хотя путем удаления указателя на базовый класс Base. (Это намерение виртуальных деструкторов.)

  3. Деструкторы всех базовых классов также называются (как и конструкторы, но в обратном порядке).

...