Вызов не шаблонного конструктора базового класса в классе, полученном из шаблонного посредника - PullRequest
3 голосов
/ 14 июля 2011
template <class WndClass>
class screenhelpers : public WndClass
{
public:
    typedef WndClass BaseClass;
    typedef typename screenhelpers<WndClass> ThisClass;
    CRect GetControlRect(CWnd *pControl) const
    {               
            CRect rectWindow(0,0,0,0);
            if (!pControl)
                    return rectWindow;
            pControl->GetWindowRect(&rectWindow);
            this->ScreenToClient(&rectWindow);
            return rectWindow;
    }
};

class MyDialog : public screenhelpers<CDialog>
{
public:
    typedef screenhelpers<CDialog>::BaseClass MDialog;
    MyDialog(int i);
    MyDialog(LPCSTR lpszTemplateName, CWnd *pParentWnd);
    MyDialog(int nIDTemplate, CWnd *pParentWnd);
};

MyDialog::MyDialog(int i)
{
    BaseClass b;    
}

MyDialog::MyDialog(LPCSTR lpszTemplateName, CWnd *pParentWnd)
:    MyDialog::BaseClass(lpszTemplateName, pParentWnd)
{    
}


MyDialog::MyDialog(int nIDTemplate, CWnd *pParentWnd)
    :       MyDialog::CDialog(nIDTemplate, pParentWnd)
{
}

Я не понимаю, почему я не могу вызвать базовый класс screenhelpers.

Если MyDialog наследует от screenhelpers, а screenhelpers наследует от CDialog, почему я не могу вызвать CDialog?

Ответы [ 2 ]

3 голосов
/ 14 июля 2011

Список инициализации в конструкторе может вызывать только конструктор его непосредственного родителя, а не один далее по цепочке.Вот почему вы не можете инициализировать CDialog напрямую.

Ваш класс screenhelpers не определяет конструктор, который принимает два параметра, поэтому он также не будет работать.Даже если вы добавите такой конструктор, я не уверен, что это правильный синтаксис для ссылки на него по имени typedefed, вам может понадобиться использовать screenhelpers<CDialog>.

1 голос
/ 14 июля 2011

Если бы конструктору MyDialog было разрешено вызывать конструктор CDialog, последний будет вызван дважды: один раз MyDialog и один раз screenhelpers.Это было бы катастрофой.

Если вам нужно контролировать, как конструктор CDialog вызывается из MyDialog, вам нужно использовать виртуальное наследование:

template <class WndClass>
class screenhelpers : public virtual WndClass

Тогда вы иметь (а не просто иметь возможность) вызывать конструктор CDialog из MyDialog.

Обратите внимание, что это может иметь другие последствия для вашего дизайна.

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