Re: Benefits of Protected Construtors in MFC

Tech-Archive recommends: Repair Windows Errors & Optimize Windows Performance



See below...
On Thu, 22 May 2008 03:16:01 -0700, sawer <sawer@xxxxxxxxxxxxxxxxxxxxxxxxx> wrote:

Hi

I want to ask you about logic behind the protected constructors in MFC.
Firstly i want to give an example. This make easier to explain the problem.

I added a class which is driven from CView class. And i want to show it when
clicked "View->New Window" menu.
***********************
#pragma once


// code view

class code : public CView
{
DECLARE_DYNCREATE(code)

protected:
code(); // protected constructor used by dynamic creation
virtual ~code();

public:
virtual void OnDraw(CDC* pDC); // overridden to draw this view
#ifdef _DEBUG
virtual void AssertValid() const;
#ifndef _WIN32_WCE
virtual void Dump(CDumpContext& dc) const;
#endif
#endif

protected:
DECLARE_MESSAGE_MAP()
};
*************************

I can not call like this:
CView* pView = (CView*) new code; // error C2248 cannot access protected
member
****
That's correct. You cannot access the protected member. Why would you want to? Doing
'new code' makes no sense. If you want a new view, you would create the new view using
the supported interfaces, which not only create the view, but initialize it properly.
****

1-) Why are the wizard declare classes constructors protected or private?
What is the benefit/logic? For example If i add class which is derived from
CEdit with wizard, its constructors is declared public but if it is derived
from CEditView its constructor is declared protected. Why is that so?
****
Because view constructors are protected for a reason: you are not supposed to be calling
them. So, deliberately, they are made protected. The rationale is that you do not know
how to create a view; it is more than just allocating an object. So don't do it. Do it
the right way.
****

2-)Is changing protected to public best way?
****
No, it will do the wrong thing, and you will not be happy with the result. Why are you
confusing the concept of "create a new view" with "use the new operator"?
****

3-) Where must i handle the menu selection, i mean creating new form. In
MainFrm.cpp or something else?
****
I usually do this in the CMainFrame class; here's the code

I did this from the mainfrm.cpp file. The code goes like this:

Add a protected variable to the mainframe class:

CMultiDocTemplate * GreenTemplate;

In the CMainFrame::CMainFrame constructor, clear it out
GreenTemplate = NULL;
Add a new protected class member function
CDocument * GetCurrentDocument();
For symmetry, I added an additional variable
CMultiDocTemplate * RedTemplate;
and set it to NULL as well.

Create a new CView-derived class, in my case CGreenView (the names have been sanitized to
protected certain secure information).

The default view is a Red view, as exemplified by the standard InitInstance code:

pDocTemplate = new CMultiDocTemplate(IDR_RedViewTYPE,
RUNTIME_CLASS(CMultiViewDoc),
RUNTIME_CLASS(CChildFrame), // custom MDI child frame
RUNTIME_CLASS(CRedView));
if (!pDocTemplate)
return FALSE;
AddDocTemplate(pDocTemplate);


I added the following:

a new menu

#define IDR_GreenViewTYPE (xxx)

where xxx is a resource number you have not already used. In my case it was 130. It has
to have an ICON of that ID, and a STRINGTABLE resource of that ID, so the ID numeric value
cannot be used already in either a string, icon, or menu context.

I added to the Window menu of the exisiting IDR_RedViewTYPE the item
&Green View = ID_WINDOW_GREENVIEW
and to the new menu for the IDR_GreenViewTYPE the item
&Red View = ID_WINDOW_REDVIEW


I Created an icon of the ID IDR_GreenTYPE.

In mainfrm.cpp, I added the handler to create a Green View:

CDocument * CMainFrame::GetCurrentDocument()
{
CMDIFrameWnd * frame = (CMDIFrameWnd*)AfxGetApp()->m_pMainWnd;
if(frame == NULL)
return NULL;
CMDIChildWnd * child = (CMDIChildWnd *)frame->GetActiveFrame();
if(child == NULL)
return NULL;
CView * view = child->GetActiveView();
if(view == NULL)
return NULL;
CDocument * doc = view->GetDocument();
return doc;
} // CMainFrame::GetCurrentDocument

void CMainFrame::OnWindowGreenview()
{
if(GreenTemplate == NULL)
GreenTemplate = new CMultiDocTemplate(IDR_GreenViewTYPE,
RUNTIME_CLASS(CMultiViewDoc),
RUNTIME_CLASS(CChildFrame),
RUNTIME_CLASS(CGreenView));

CMultiViewDoc * doc = (CMultiViewDoc *)GetCurrentDocument();
CFrameWnd * frame = GreenTemplate->CreateNewFrame(doc, NULL);
if(frame != NULL)
{ /* frame created */
frame->InitialUpdateFrame(doc, TRUE);
} /* frame created */
}

void CMainFrame::OnUpdateWindowGreenview(CCmdUI *pCmdUI)
{
CMultiViewDoc * doc = (CMultiViewDoc *)GetCurrentDocument();
pCmdUI->Enable(doc != NULL);
}

And one for a Red view:

void CMainFrame::OnWindowRedview()
{
if(RedTemplate == NULL)
RedTemplate = new CMultiDocTemplate(IDR_RedViewTYPE,
RUNTIME_CLASS(CMultiViewDoc),
RUNTIME_CLASS(CChildFrame),
RUNTIME_CLASS(CRedView));

CMultiViewDoc * doc = (CMultiViewDoc *)GetCurrentDocument();
CFrameWnd * frame = RedTemplate->CreateNewFrame(doc, NULL);
if(frame != NULL)
{ /* frame created */
frame->InitialUpdateFrame(doc, TRUE);
} /* frame created */
}

void CMainFrame::OnUpdateWindowRedview(CCmdUI *pCmdUI)
{
CMultiViewDoc * doc = (CMultiViewDoc *)GetCurrentDocument();
pCmdUI->Enable(doc != NULL);
}

To the destructor CMainFrame::~CMainFrame add
delete RedTemplate;
delete GreenTemplate;


****



If you help me to understand this concept i will be very glad
Joseph M. Newcomer [MVP]
email: newcomer@xxxxxxxxxxxx
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
.



Relevant Pages

  • Re: Benefits of Protected Construtors in MFC
    ... I use public constructors when I have embedded FormViews derived from a class which lives in a static library. ... > virtual void Dumpconst; ... CMultiDocTemplate * GreenTemplate; ... cannot be used already in either a string, icon, or menu context. ...
    (microsoft.public.vc.mfc)
  • Re: [PHP] How can I do this -- method chaining
    ... I believe constructors return void, ... the 'new' keyword returns a copy of the object. ... public static function getInstance() { ...
    (php.general)
  • Re: template copy constructor
    ... auto_ptr without template functions, and it works. ... That's because you don't have any constructors from "wrong" odd_ptr ... X& operator*const throw; ... void resetthrow; ...
    (microsoft.public.vc.language)
  • Re: Best way to develop in parallel
    ... Both have exactly the same method signatures, constructors, etc. ... How can I easily switch between the classes? ... Have the test code refer to the interface and construct one or the other based on some condition. ... void testB() ...
    (comp.lang.java.help)
  • Re: Multiple views Single Document MDI
    ... CMultiDocTemplate * GreenTemplate; ... cannot be used already in either a string, icon, or menu context. ... void CMainFrame::OnWindowGreenview ... I dont know whether creating multiple document templates is a good ...
    (microsoft.public.vc.mfc)