Правильно ли использовать конструктор по умолчанию с полиморфизмом? - PullRequest
2 голосов
/ 01 августа 2010

У меня в принципе есть что-то вроде этого:

class CGlToolBase
{
public:
    CGlToolBase(void)
    {

    }
    virtual void OnMouseDown(CGlEngine &glEngine, WPARAM wParam, LPARAM lParam);
    virtual void OnMouseMove(CGlEngine &glEngine, WPARAM wParam, LPARAM lParam);
    virtual void OnMouseUp(CGlEngine &glEngine, WPARAM wParam, LPARAM lParam);
    virtual void OnKeyDown(CGlEngine &glEngine, WPARAM wParam, LPARAM lParam);
    virtual void OnLDoubleClick(CGlEngine &glEngine, WPARAM wParam, LPARAM lParam);
    ~CGlToolBase(void);
};

class CGlToolSelect : public CGlToolBase
{
   bool selected;
public:
    CGlToolSelect(void)
    {
     selected = false;
    }
    virtual void OnMouseDown(CGlEngine &glEngine, WPARAM wParam, LPARAM lParam);
    virtual void OnMouseMove(CGlEngine &glEngine, WPARAM wParam, LPARAM lParam);
    virtual void OnMouseUp(CGlEngine &glEngine, WPARAM wParam, LPARAM lParam);
    virtual void OnKeyDown(CGlEngine &glEngine, WPARAM wParam, LPARAM lParam);
    virtual void OnLDoubleClick(CGlEngine &glEngine, WPARAM wParam, LPARAM lParam);
    ~CGlToolSelect(void);
};

В моем инструменте выбора я установил для выбранного значение false. Это правильный способ сделать это, если я сделаю что-то вроде этого:

CGlToolBase *tool = new CGlToolSelect;

Спасибо

Ответы [ 2 ]

3 голосов
/ 01 августа 2010

Это совершенно законно и приемлемо.

Однако, некоторые примечания:

Ваш деструктор должен быть виртуальным. Если у какого-либо класса есть виртуальные методы (абстрактные или нет), у вас должен быть общедоступный виртуальный (абстрактный?) Деструктор (поэтому delete вызывает дочерние деструкторы) или защищенный не виртуальный деструктор (который не позволяет суперклассу быть delete d как суперкласс (он должен быть delete d как подкласс, таким образом вызывая соответствующий деструктор)).

Вы можете использовать инициализаторы для установки selected в конструкторе:

CGlToolSelect() :
    selected(false)
{
}
0 голосов
/ 11 мая 2012

Правильно ли использовать конструктор по умолчанию с полиморфизмом?

CGlToolBase * tool = new CGlToolSelect;

Конечно - вы заметили, что аргумент new равен CGlToolSelect - в момент выделения памяти и вызова конструктора точный класс известен компилятору. Правильный конструктор производного класса используется без необходимости отправки virtual. Какой конструктор вы используете, и, в частности, является ли он конструктором по умолчанию (т. Е. Не имеет неназначенных аргументов), совершенно не имеет значения: любой из них будет работать идеально.

Отдельно - после построения у вызывающей области есть только объект CGlToolBase*, и он не обязательно знает реальный тип времени выполнения объекта во время его удаления, поэтому и нужно запустить При использовании соответствующего конструктора типа time вам нужно искать его, используя запись в указанном объекте: виртуальные функции создают именно такую ​​запись (запись в таблице виртуальной диспетчеризации), поэтому создание виртуального деструктора решает эту проблему вызова правильный деструктор. В вашем конкретном примере может показаться, что это не имеет значения, поскольку производный класс не вводит никаких дополнительных членов с собственными деструкторами, которые нужно вызывать, но помните, что ваш производный класс сам по себе может быть производным, а те - более производными. классы могут вводить элементы данных, которые нуждаются в надлежащем уничтожении для освобождения ресурсов, таких как память кучи, файловые дескрипторы, разделяемая память, блокировки и т. д. Опять же, создание виртуального деструктора обеспечивает правильное обращение к деструктору самого производного класса и вызов классов вернуться через непосредственные базовые классы к деструктору базового класса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...