|
Hello everyone,
Some people doubt that the design below is inferior compared to design which makes f, either Foo* or Foo&. The reason is below design will waste memory space and degrade performance by creating a new instance.
I think it depends. If we really needs to wrap a new instance, I think the following design is fine. If we needs to refers to an existing instance, this design is inferior because it will waste memory space and degrade performance by creating a new instance and destroy the original one.
class Foo;
class Goo
{
Foo f;
}
thanks in advance,
George
|
|
|
|
|
You are missing an important point here. Everything is not related to performances only. In this case, it will make a huge difference if you are using a new class instance instead of a reference or a pointer to an existing instance: this will be a copy of the original object, which means that all the modifications you do on this copy won't affect the original object (which is the case when you use a reference or a pointer).
You have to think about that before taking into account performances issues, because it has a major impact on the design of your program.
|
|
|
|
|
Thanks Cedric,
You mean none of the 3 designs are always good or bad, it depends on requirement, right?
regards,
George
|
|
|
|
|
|
Thanks Cedric,
regards,
George
|
|
|
|
|
George_George wrote: If we really needs to wrap a new instance, I think the following design is fine
Indeed:
- You cannot wrap a new istance by means of reference.
- Dynamically allocation of new instance is usually a bad idea (you may forget cleanup).
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
|
|
|
|
|
Thanks CPallini,
CPallini wrote: You cannot wrap a new istance by means of reference.
What means "wrap a new istance by means of reference"? Could you give more description or show some pseudo code please?
regards,
George
|
|
|
|
|
It's simple: reference variable must alway be assigned. Hence you need to pass an object to the class,
that is, you're making a reference to an existing object.
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
|
|
|
|
|
Thanks for clarification for this.
regards,
George
|
|
|
|
|
We have historically had so much trouble with 'lost' pointers, that we embed 'cookies' to our other objects within others, instead of the pointers themselves. If you have a pointer to an object, it is hard to tell if the object is still around, unless you have the address of a smart pointer that won't let object delete until all references to the object are gone. If you use cookies, you can ask a lookup table to translate cookie for you, and if that is gone, then object is gone too.
|
|
|
|
|
Thanks Blake,
I am interested to learn what do you mean embed 'cookies'. Do you show some pesudo code or refer some links please?
regards,
George
|
|
|
|
|
Suppose I have a list of instances of objects of type "Class A".
Now I want to refer to those Class A objects by specific instance from another class, let's say Class B.
Traditionally, you would have placed a pointer or some reference to the Class A instance within Class B:
class B<br />
{<br />
...<br />
class A* m_pA;<br />
...<br />
};
But instead, if you give every instance of class A a 'cookie', such as a unique 32-bit DWORD value:
class A{<br />
...<br />
DWORD m_Cookie;<br />
...<br />
};
And then you palce all the instances of Class A into a map, mapping the cookie to the pointer to Class A (So now the pointer to class A is in exactly one place).
Then when you need class B to refer to a specific instance of Class A, instead of using the pointer to Class A, you store its cookie value:
class B
{
...
DWORD m_CookieToA;
...
};
Then when you need to get to a Class A instance from a member function of Class B, you can use the map to look for the cookie for the related Class A. If the map gives you back a value, then you get back a good pointer to class A, and if not, then there is no Class A with that cookie in existence.
If the lifetime of Class A objects will outlive Class B objects, this is fine either way - pointer or cookie.
Otherwise, you might want to provide some synchronization on the map (unless your program is single threaded) so things are not removed from the Class A map while a Class B member function retains or is using a pointer to a Class A object. Otherwise, you are free to delete Class A objects at will, without trying to patch up your Class B objects which might have stored pointers to the Class A instances.
So, you can ask yourself, if it is more important not to crash or to have performance, as the other member mentioned. This technique is not as 'quick' as storing the pointer to Class A within Class B, as far as the quickest reference to Class A from within a Class B member function (you have to look up the cookie in the map each time to fetch the temporary pointer to Class A).
If you wanted to get fancy, you could use a multimap for Class A, and map Class A address, Class A cookie, and the number of references to class A in the map. The reference count would be udpated each time you assigned a cookie to an A to a B. That way, you would know, as yuo were about to delete a Class A instance, if there were any outstanding Class B referring to it.
|
|
|
|
|
Cool, Blake!
Your answer is clear.
regards,
George
|
|
|
|
|
Hello everyone,
Two questions about re-entrancy issue,
http://www.codeproject.com/KB/COM/sta_issues.aspx
1. What is the setback of the issue? I think it is still thread-safe since only one STA owning thread will execute on STA component;
2. How to avoid it in design?
thanks in advance,
George
|
|
|
|
|
Hi all,
i m create a property sheet and show property pages in this property sheet.
When i run the application the Property Sheet Show Three Buttons "OK","CANCEL",and "APPLY" at the bottom .and the apply button is Disabled.
How can Remove all these buttons from Property Sheet.
this is my Code::
class CMyPropertySheet : public CPropertySheet
{
DECLARE_DYNAMIC(CMyPropertySheet)
public:
CMyPropertySheet(LPCTSTR pszCaption, CWnd* pParentWnd = NULL, UINT iSelectPage = 0);
virtual ~CMyPropertySheet();
static int CALLBACK XmnPropSheetCallback(HWND hWnd, UINT message, LPARAM lParam);
DECLARE_MESSAGE_MAP()
public:
virtual BOOL OnInitDialog();
HICON m_hIcon;
CPropertyPage1 m_Page1;
CPropertyPage2 m_Page2;
CPropertyPage3 m_Page3;
CPropertyPage4 m_Page4;
CPropertyPage5 m_Page5;
protected:
BOOL m_bNeedInit;
CRect m_rCrt;
int m_nMinCX;
int m_nMinCY;
public:
afx_msg void OnSize(UINT nType, int cx, int cy);
afx_msg void OnGetMinMaxInfo(MINMAXINFO* lpMMI);
virtual INT_PTR DoModal();
//////////////////////////////////////////////////////////////////////
CMyPropertySheet::CMyPropertySheet(LPCTSTR pszCaption, CWnd* pParentWnd, UINT iSelectPage)
:CPropertySheet(pszCaption, pParentWnd, iSelectPage)
, m_bNeedInit(TRUE)
, m_nMinCX(0)
, m_nMinCY(0)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
AddPage(&m_Page1);
AddPage(&m_Page2);
AddPage(&m_Page3);
AddPage(&m_Page4);
AddPage(&m_Page5);
}
CMyPropertySheet::~CMyPropertySheet()
{
}
BEGIN_MESSAGE_MAP(CMyPropertySheet, CPropertySheet)
ON_WM_SIZE()
ON_WM_GETMINMAXINFO()
ON_WM_CLOSE()
END_MESSAGE_MAP()
// CMyPropertySheet message handlers
BOOL CMyPropertySheet::OnInitDialog()
{
this->SetIcon(m_hIcon,TRUE);
BOOL bResult = CPropertySheet::OnInitDialog();
// Adjust property sheet size to account for the new menu.
CRect r; GetWindowRect(&r);
r.bottom += GetSystemMetrics(SM_CYMENU);
MoveWindow(r);
// ...
// Init m_nMinCX/Y
m_nMinCX = r.Width();
m_nMinCY = r.Height();
// After this point, the resize code runs.
m_bNeedInit = FALSE;
GetClientRect(&m_rCrt);
return bResult;
}
// This function must be a STATIC method.
// Callback to allow you to set the default window styles
// for the property sheet.
int CALLBACK CMyPropertySheet::XmnPropSheetCallback(HWND hWnd, UINT message, LPARAM lParam)
{
extern int CALLBACK AfxPropSheetCallback(HWND, UINT message, LPARAM lParam);
// XMN: Call MFC's callback.
int nRes = AfxPropSheetCallback(hWnd, message, lParam);
switch (message)
{
case PSCB_PRECREATE:
// Set your own window styles.
((LPDLGTEMPLATE)lParam)->style |= (DS_3DLOOK | DS_SETFONT
| WS_OVERLAPPEDWINDOW | WS_POPUP | WS_VISIBLE | WS_CAPTION);
break;
}
return nRes;
}
void CMyPropertySheet::OnSize(UINT nType, int cx, int cy)
{
CPropertySheet::OnSize(nType, cx, cy);
CRect r1;
if (m_bNeedInit)
return;
CTabCtrl *pTab = GetTabControl();
ASSERT(NULL != pTab && IsWindow(pTab->m_hWnd));
int dx = cx - m_rCrt.Width();
int dy = cy - m_rCrt.Height();
GetClientRect(&m_rCrt);
HDWP hDWP = ::BeginDeferWindowPos(5);
pTab->GetClientRect(&r1);
r1.right += dx; r1.bottom += dy;
::DeferWindowPos(hDWP, pTab->m_hWnd, NULL,
0, 0, r1.Width(), r1.Height(),
SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOZORDER);
// Move all of the buttons with the lower and right sides.
for (CWnd *pChild = GetWindow(GW_CHILD);
pChild != NULL;
pChild = pChild->GetWindow(GW_HWNDNEXT))
{
if (pChild->SendMessage(WM_GETDLGCODE) & DLGC_BUTTON)
{
pChild->GetWindowRect(&r1); ScreenToClient(&r1);
r1.top += dy; r1.bottom += dy; r1.left+= dx; r1.right += dx;
::DeferWindowPos(hDWP, pChild->m_hWnd, NULL,
r1.left, r1.top, 0, 0,
SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOZORDER);
}
// Resize everything else.
else
{
pChild->GetClientRect(&r1);
r1.right += dx; r1.bottom += dy;
::DeferWindowPos(hDWP, pChild->m_hWnd, NULL, 0, 0,
r1.Width(), r1.Height(),
SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOZORDER);
}
}
::EndDeferWindowPos(hDWP);
}
void CMyPropertySheet::OnGetMinMaxInfo(MINMAXINFO* lpMMI)
{
lpMMI->ptMinTrackSize.x = m_nMinCX;
lpMMI->ptMinTrackSize.y = m_nMinCY;
CPropertySheet::OnGetMinMaxInfo(lpMMI);
}
INT_PTR CMyPropertySheet::DoModal()
{
// Hook into property sheet creation code
m_psh.dwFlags |= PSH_USECALLBACK;
m_psh.pfnCallback = XmnPropSheetCallback;
return CPropertySheet::DoModal();
}
Thanks in advance.
|
|
|
|
|
Get window handles of each of the buttons and hide and disable the buttons. Make sure the focus is not on them when doing so. Also, if you have other buttons, you might want to make one of them the defualt button.
|
|
|
|
|
hi all,
i want to create a dialog box same like as we click on Start button of Windows Explorer.
i want to set a focus on one button like (Start Button) at bottom,
from that button i want to call a dialog box on which my child window controls are present.
i am using a dialog box for that bottom button, after click on that button i want to set focus on the another dialog box
plz help me out from dis..
Pankaj
|
|
|
|
|
I think I saw an article I think it was nearly your answer but I dont know I saw it on the codeproject or other place.
|
|
|
|
|
Hi all,
i m using this code for creating a menu on Right Button Down of Mouse.
HMENU hMenu = ::CreatePopupMenu();
if (NULL != hMenu)
{
// add a few test items
::AppendMenu(hMenu, MF_STRING, 1, "Item 1");
::AppendMenu(hMenu, MF_STRING, 2, "Item 2");
::AppendMenu(hMenu, MF_STRING, 3, "Item 3");
ClientToScreen(&point);
int sel = ::TrackPopupMenuEx(hMenu,
TPM_CENTERALIGN | TPM_RETURNCMD,
point.x,
point.y,
m_hWnd,
NULL);
::DestroyMenu(hMenu);
it works but i dot no how can take action on its items.
Anyone can help me about this.
Thanks in advance.
|
|
|
|
|
Yeah, sure. The 1, 2 & 3 (3rd parameter) are used as the commandIDs.
When a particular menu option is chosen, this commandID will be sent to your windowProcedure in LOWORD of wParam.
So, what you need to do with the above code is look for 1, 2 or 3 as being the ID of the control that generated a WM_COMMAND message. An rough example may be seen in this code I just ripped out of a class, just pay attention to the way the messages are created and caught.
LRESULT WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_COMMAND:
switch LOWORD(wParam)
{
case <code>IDM_LargeIcons</code>:
SetIconStyle(LARGE);
break;
case <code>IDM_SmallIcons</code>:
SetIconStyle(SMALL);
break;
case <code>IDM_Details</code>:
SetIconStyle(DETAIL);
break;
case <code>IDM_List</code>:
SetIconStyle(LIST);
break;
}
break;
case WM_RBUTTONDOWN:
POINT CurPos;
GetCursorPos(&CurPos);
HMENU hPopupMenu = CreatePopupMenu();
InsertMenu(hPopupMenu, 0, MF_BYPOSITION | MF_STRING, <code>IDM_LargeIcons</code>, "Large Icons");
InsertMenu(hPopupMenu, 1, MF_BYPOSITION | MF_STRING, <code>IDM_SmallIcons</code>, "Small Icons");
InsertMenu(hPopupMenu, 2, MF_BYPOSITION | MF_STRING, <code>IDM_List</code>, "List");
InsertMenu(hPopupMenu, 3, MF_BYPOSITION | MF_STRING, <code>IDM_Details</code>, "Details");
SetForegroundWindow(GetHwnd());
TrackPopupMenu(hPopupMenu, TPM_TOPALIGN | TPM_LEFTALIGN, CurPos.x, CurPos.y, 0, GetHwnd(), NULL);
DestroyMenu(hPopupMenu);
return 0;
}
return WndProcDefault(hWnd, uMsg, wParam, lParam);
}
The easiest way to make the world a better place is to refuse to help those that wreck it....
|
|
|
|
|
Can you use of context menu,did you declare functions for these id menus.
|
|
|
|
|
Hi all,
I want to find files which are present in a particular folder.
how can i do it???
Thanks in advance
|
|
|
|
|
You may use FindFirstFile and FindNextFile functions, see [^].
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
|
|
|
|
|
Hi Experts,
If a process is locked by another process how can I unlock it?
|
|
|
|
|
Hi,
If u are looking for some softs there is Unlocker, u can donload it on http://ccollomb.free.fr/unlocker/unlocker1.8.6.exe[^]
Or if u can exec the command "taskkill /F /Num PID" but u need to enter the appropriate PID Of the process. I don't know how u can get the PID of the process but may be if u look more under the Dos commands u will find it.
"The Ultimate Limit Is Only Your Imagination."
|
|
|
|
|