簡體   English   中英

在從模板化中介派生的 class 中調用非模板基 class 構造函數

[英]Calling non-template base class constructor in class derived from templated intermediary

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)
{
}

我不明白為什么我似乎不能調用屏幕助手的基本 class。

如果MyDialog繼承自screenhelpers,screenhelpers繼承自CDialog,為什么不能調用CDialog呢?

構造函數中的初始化列表只能調用其直接父級的構造函數,而不是更上一層的構造函數。 這就是你不能直接初始化 CDialog 的原因。

您的屏幕助手 class 沒有定義帶有兩個參數的構造函數,因此這也不起作用。 即使您添加了這樣的構造函數,我也不確定通過 typedefed 名稱引用它的語法是否有效,您可能需要改用screenhelpers<CDialog>

如果允許MyDialog構造函數調用CDialog構造函數,則后者將被調用兩次:一次由MyDialog調用,一次由screenhelpers 那將是一場災難。

如果需要控制如何從MyDialog調用CDialog構造函數,則需要使用虛擬 inheritance:

template <class WndClass>
class screenhelpers : public virtual WndClass

然后,您(不僅能夠)從MyDialog調用CDialog構造函數。

請注意,這可能會對您的設計產生其他影響。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM