|
Hi,
Just to expand a little further...when I execute the program the correct constructor is in fact called based upon const-ness. But what I need is confirmation that this is correct well-formed C++ and that it will compile correctly on other compilers. As this is only a warning (as opposed to an error) I just want to make sure that what I am attempting is not somehow dangerous or insecure.
If it isn't dangerous (or insecure) I will just use:
#pragma warning(disable: 4521)
Thanks again,
Lea Hayes
|
|
|
|
|
lhayes00 wrote: The entire procedure can be optimised very easily when a non-constant version of the object is supplied:
Could you elaborate on that point ? That seems a bit akward to me. Maybe that would be a better solution: be able to optimise the procedure on a const object (if at all possible).
|
|
|
|
|
Without knowing how the optomization works, I am limited. If the non-const copy constructor doesn't change the source in any significant way, you might be able to declare certain members mutable . If the copy constructor destroys the source object, you might want to implement it as a swap function. In either case, I can imagine special cases that would require alternative methods.
Nathan
|
|
|
|
|
Hi,
Thankyou very much....I didn't know about the 'mutable' keyword....I can see that being very useful.
|
|
|
|
|
I don't understand, are you wanting to modify the copy_from when copying it to a new AClass ?
the AClass(const AClass& copy_from); should be sufficient; the const applies to the parameter inside the method, not outside.
You could call the copy constructor with a const AClass or a non const AClass.
for example
void SomeClass::DoSomething( const AClass& c)
{
AClass newClass = c;
}
or
void SomeClass::DoSomethingElse( AClass& c)
{
AClass newClass = c;
}
|
|
|
|
|
Hi,
The non-constant version does make changes to the copy_from object. When an object of the type AClass is returned from a method, it can be flagged.
AClass BClass::DoSomething()<br />
{<br />
AClass myObject;<br />
...<br />
myObject.IndicateReturn();<br />
return myObject;<br />
}<br />
<br />
<br />
AClass::AClass(AClass& copy_from)<br />
{<br />
if(copy_from.IsReturnIndicated())<br />
Swap(copy_from);<br />
else<br />
Copy(copy_from);<br />
}<br />
<br />
AClass::AClass(const AClass& copy_from)<br />
{<br />
Copy(copy_from);<br />
}
|
|
|
|
|
lhayes00 wrote: When an object of the type AClass is returned from a method, it can be flagged.
I have no idea what you are doing but my best guess is you have some design flaws that are causing your copy constructor issue. To achieve an optimal solution you would have to fix those flaws first.
|
|
|
|
|
I don't know what you are trying to achieve, but even if you were to manage to have two different copy constructors now, I think you would be laying a maintenance minefield. Reading your code it is not easy to understand which version will be invoked and what happens. Seeing
AClass a(b)
gives no clue that b is modified. You, or others, may not recall this when maintaining the code.
If possible, implement the const copy constructor that uses a const object.
Think of a good descriptive name to call the non-const version, and do a two-step construction, if necessary creating a separate constructor to create an empty or invalid object, e.g.
AClass a;<br />
a.CopyFromAndModify(b);
If these are always created on the heap you could make a simple helper function to do the work
AClass* pA = CreateNewClassAndModify(b);
I'm sure there are other ways.
Peter
"Until the invention of the computer, the machine gun was the device that enabled humans to make the most mistakes in the smallest amount of time."
|
|
|
|
|
How can be made empty the keyboard buffer in VC++6?
36. When you surround an army, leave an outlet free.
...
Do not press a desperate foe too hard.
SUN-TZU - Art of War
|
|
|
|
|
RomTibi wrote: How can be made empty the keyboard buffer in VC++6?
If it is a windows app, you can use PeekMessage to eat all the pending key press messages.
Nathan
|
|
|
|
|
Thanks a lot!
36. When you surround an army, leave an outlet free.
...
Do not press a desperate foe too hard.
SUN-TZU - Art of War
|
|
|
|
|
(also posted on the dundas forum)
I'm using the Dundas grid to display a simple grid.
In one of the cell, I use the Ellipsis Cell type, it's a cell type with a "..." button to call up a dialog.
When I click on the "..." button my dialog is called, but it's not "modal", the grid still has focus and I can click the button again and again. seems the dialog message loop is overridden for at least one message, if I click on the dialog, the dialog really become modal.
This code is copied from the cell type Dundas sample. ( and I tried the same thing with the dundas demo to see if the problem is in my code )
int CMbJobInfoGrid::OnEllipsisButton(long ID,int col,long row,long msg,long param){
CUGCell cell;
GetCell(col,row,&cell);
int nCellTypeIndex = cell.GetCellType();
if(msg == UGCT_ELLIPSISBUTTONCLICK)
{
CMbEditCommentDialog dlg();
dlg.DoModal();
}
return TRUE;
}
It's a small problem, but it's bugging and I'm not certain why the DoModal does really eat the messages, and there's one message that get handled by the underlying grid.
Thanks.
Solution : There was SetCapture that was not supposed to be there. I removed it, tested all relevant code and behaviour and now everything is ok; no need to disable parent window or do other things, DoModal works as is should.
modified on Friday, December 07, 2007 3:51:44 PM
|
|
|
|
|
Modal dialogs in MFC are not really modal, and I believe that this allows for better message handling in the MFC framework. Modal dialogs just disable their parent to simulate a modal dialog.
You should be able to manually disable the dialog's parent to get around this problem.
Peace!
-=- James Please rate this message - let me know if I helped or not!<hr></hr> If you think it costs a lot to do it right, just wait until you find out how much it costs to do it wrong! Avoid driving a vehicle taller than you and remember that Professional Driver on Closed Course does not mean your Dumb Ass on a Public Road! See DeleteFXPFiles
|
|
|
|
|
callback (p1, p2, p3, ....)
{
CView *pView = (CView *)p1
pView->whatever() causes ASSERT as defined in wincore.cpp - void CWnd::AssertValid()
}
MainApp{
CDocument::OnCommand - selected some operation from menu
CView *pView = get active view
call DLL (pView, p2, p3, ...)
}
DLL {
put up dialog
move slider, now need to update pView in main app
callback(pView, p2, p3 ...)
}
No matter if I pass a ptr to CDocument or CView the callback will fail (ASSERT) someplace
If I pass in the HWND and in the callback use CWnd::FromHandle() and then call InvalidateRect() I can get thinks to redraw but I want to access items in the Doc or View.
The ASSERT code states
// Note: if either of the above asserts fire and you are
// writing a multithreaded application, it is likely that
// you have passed a C++ object from one thread to another
// and have used that object in a way that was not intended.
// (only simple inline wrapper functions should be used)
//
// In general, CWnd objects should be passed by HWND from
// one thread to another. The receiving thread can wrap
// the HWND with a CWnd object by using CWnd::FromHandle.
//
// It is dangerous to pass C++ objects from one thread to
// another, unless the objects are designed to be used in
// such a manner.
So does anyone have a way around this?
Thanks in advance
Tony Teveris
Gerber Scientific Products
Senior Software Engineer
Phone: 860 648 8151
Fax: 860 648 8214
83 Gerber Road West
South Windsor, CT 06074
|
|
|
|
|
Tony Teveris wrote: So does anyone have a way around this?
Does anyone include Microsoft[^] ? 
|
|
|
|
|
I don't see anything in your sample code that shows different threads.
Am I missing something?
Calls across the EXE/DLL boundary should be safe, unless the DLL is linked
to a separate MFC library, in which case all bets are off.
The only way this will work is to use a true MFC extension DLL[^].
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
If the DLL is displaying a dialog and the dialog code through it's messageing calls the callback is there a problem. Do dialogs operate in the same thread or different ?
When I first did this I thought that same as you but it does fail. In the DLL I am using some 3rd part imaging software (LEAD) but it all links with the same liraries.
Tony Teveris
Gerber Scientific Products
Senior Software Engineer
Phone: 860 648 8151
Fax: 860 648 8214
83 Gerber Road West
South Windsor, CT 06074
|
|
|
|
|
Unless you've left out some code, it's all on one thread.
As shown, there's only one message loop - running in the EXE's CWinApp object.
How is the dialog created in the DLL? Does the dialog use a different thread
for it's message loop?
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
the DLL function
AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
nRet = DoDialogBoxParam(IDD_BCI_DLG, hParentWnd, (DLGPROC)BCIDlgProc, (LPARAM) pBciDlgData);
the partent windows is that of the main app, the dialog resource is in the DLL
Tony Teveris
Gerber Scientific Products
Senior Software Engineer
Phone: 860 648 8151
Fax: 860 648 8214
83 Gerber Road West
South Windsor, CT 06074
|
|
|
|
|
DoDialogBoxParam? I meant at the MFC/Win32 level -
I have no idea what your functions do
Is the dialog created using MFC or Win32? Modal or modeless?
Also important is what type of DLL you're using - MFC extension DLL or
regular DLL linked to MFC (see Kinds of DLLs[^]).
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Sorry about that
DLGPROC pfn;
pfn = (DLGPROC) MakeProcInstance((FARPROC) pfnDialog, AfxGetApp()->m_hInstance);
nRet = (L_INT) DialogBoxParam(AfxGetApp()->m_hInstance, MAKEINTRESOURCE(nDialog), hWnd, pfn, lParam);
FreeProcInstance((FARPROC) pfn);
Regular DLL using / linked with MFC (NOT static, same as main app)
within wincore.cpp here is where it fails
// should be a normal window
ASSERT(::IsWindow(m_hWnd));
// should also be in the permanent or temporary handle map
CHandleMap* pMap = afxMapHWND();
ASSERT(pMap != NULL);
I have to ask the programmer of the main app some questions. I agree with you so far so I think there has to be something in our code messing something up.
Tony Teveris
Gerber Scientific Products
Senior Software Engineer
Phone: 860 648 8151
Fax: 860 648 8214
83 Gerber Road West
South Windsor, CT 06074
|
|
|
|
|
Tony Teveris wrote: I have to ask the programmer of the main app some questions.
Yes
The module state stuff can affect CWnd pointers across the EXE/DLL
module boundary depending on the type of DLL. This needs to be managed correctly.
The CHandleMap is related to the module state. Your CView is in the EXE's map but in the
DLL function, you've changed the module state, so when the callback is called, the
code on the EXE side isn't finding the CView object in the DLL's map.
That's why the type of DLL is important. With a properly initialized extension DLL,
you don't need to use the AFX_MANAGE_STATE macro. Using an MFC extension DLL
is definitely the best/easiest for passing CWnds back and forth across the EXE/DLL boundary.
The drawback to an extension DLL is it can't be used by a non-MFC EXE.
If you must use a standard DLL, then you'll need to manage the module state for
your callback.
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
It is NOT an extension DLL, just a normal DLL. I see your point and will look into extension DLL or mangage the state in the callback.
I think were done here - many thanks
Tony Teveris
Gerber Scientific Products
Senior Software Engineer
Phone: 860 648 8151
Fax: 860 648 8214
83 Gerber Road West
South Windsor, CT 06074
|
|
|
|
|
Tony Teveris wrote: It is NOT an extension DLL, just a normal DLL
Cool. Try adding this to the top of the callback...
AFX_MANAGE_STATE(AfxGetAppModuleState());
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Dear all;
I have finished building an MFC Application in Microsoft visual studio 2003. Now I would like to produce an executable application which can be used in any machine.
How do i do that? please post any articles or help guidelines.
I am thankful
llp00na
|
|
|
|