|
I am learning Design Pattern and who can give me a easy example
I write some demo but I think they are not good so I wanna get some good
one that can make me understand the pattern better.
Thanks a lot!~
|
|
|
|
|
This is a meaningless question. Which pattern ? I suggest buying a good book and reading on both patterns, and their examples.
Christian Graus
No longer a Microsoft MVP, but still happy to answer your questions.
|
|
|
|
|
One more question
Product
+Method() +FactoryMethod()
| |
| |
| |
ConcreteProduct<-------------ConcreteCreator
+Method() +FactoryMethod()-----return new ConcreteProduct
In the demo code of Factory Pattern they use return to new
a ConcreteProduct object
<br />
Factory* fac = new ConcreteFactory();<br />
Product* p = fac->CreateProduct();<br />
what about using a member variabal of Creator to control Creator's behavior
like:
<br />
Product* p = new CreateProduct();<br />
Factory* fac = new ConcreteFactory(p);<br />
and use like "fac->_p->method()" to call different subclass member funtion
is it good or not to use a abstract class object as member variabal to control its behavior ???
|
|
|
|
|
|
Thanks
i am new with Disign Pattern
It's so helpful
|
|
|
|
|
I'm using ParseCommandLine to read command line arguments. I give the command line in debug mode with Project->Settings->Program Arguments. But ParseCommandLine thinks there are no args. I've seen the contents of m_lpCmdLine, and it correctly shows the args as I've given them.
So I step into ParseCommandLine, and it goes here:
void CWinApp::ParseCommandLine(CCommandLineInfo& rCmdInfo)
{
for (int i = 1; i < __argc; i++)
{
LPCTSTR pszParam = __targv[i];
BOOL bFlag = FALSE;
BOOL bLast = ((i + 1) == __argc);
if (pszParam[0] == '-' || pszParam[0] == '/')
{
bFlag = TRUE;
++pszParam;
}
rCmdInfo.ParseParam(pszParam, bFlag, bLast);
}
}
But it never enters the cycle - __argc is 0.
Interestingly, __argc is not a variable but a function, for argc it goes here
_CRTIMP int * __cdecl
AFNAME(__argc) (void)
{
return AFRET(__argc);
}
And ParseCommandLine works in another project from which I copied/pasted the code.
What might be causing this problem?
Thanks.
There is sufficient light for those who desire to see, and there is sufficient darkness for those of a contrary disposition.
Blaise Pascal
|
|
|
|
|
sashoalm wrote: But it never enters the cycle - __argc is 0.
What should it be? Have you looked at __argv[0] et al?
"Love people and use things, not love things and use people." - Unknown
"The brick walls are there for a reason...to stop the people who don't want it badly enough." - Randy Pausch
|
|
|
|
|
The command line was like this
"C:\Path\File1.pdf" "C:\Path\File2.pdf" "C:\Path\File3.pdf" "C:\Path\File4.pdf"
so __argc should be 4
And CWinApp::m_lpCmdLine shows the command line as it should be. Why ParseCommandLine doesn't work when the command line correctly reaches CWinApp::m_lpCmdLine?
There is sufficient light for those who desire to see, and there is sufficient darkness for those of a contrary disposition.
Blaise Pascal
|
|
|
|
|
But what does __argv[0] , __argv[1] , ... look like? What does your InitInstance() method look like?
"Love people and use things, not love things and use people." - Unknown
"The brick walls are there for a reason...to stop the people who don't want it badly enough." - Randy Pausch
|
|
|
|
|
class CommandLineParser : public CCommandLineInfo
{
public:
virtual void ParseParam( LPCTSTR lpszParam, BOOL bFlag, BOOL bLast )
{
...............
}
};
BOOL CMyWinApp::InitInstance()
{
AfxEnableControlContainer();
#ifdef _AFXDLL
Enable3dControls();
#else
Enable3dControlsStatic();
#endif
...............
CommandLineParser parser(m_aFileList);
ParseCommandLine(parser);
...............
return FALSE;
}
There is sufficient light for those who desire to see, and there is sufficient darkness for those of a contrary disposition.
Blaise Pascal
|
|
|
|
|
What happens if you try not using your CommandLineParser class
(just to test)...
CCommandLineInfo cmdInfo;
ParseCommandLine(cmdInfo);
I tested this by setting the Project Settings/Configuration Properties/Debugging/Command Arguments
to C:\Path\File1.pdf C:\Path\File2.pdf C:\Path\File3.pdf C:\Path\File4.pdf
and stepped into ParseCommandLine(). All four parameters are fine.
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
I added this code to my InitInstance,
int argc = __argc;
char* arg1 = __argv[0];
char* arg2 = __argv[1];
char* arg3 = __argv[2];
CommandLineParser parser(m_aFileList);
ParseCommandLine(parser);
and the count and the arguments were correctly shown when debugging. But when I step into ParseCommandLine, the arguments are wrong there (they caused an access violation so they must be NULL)!
Is this a linker problem? I use MFC as a DLL.
There is sufficient light for those who desire to see, and there is sufficient darkness for those of a contrary disposition.
Blaise Pascal
|
|
|
|
|
So have you tried this instead:
CCommandLineInfo cmdInfo;
ParseCommandLine(cmdInfo); to eliminate the possibility that your CommandLineParser class is causing problems?
"Love people and use things, not love things and use people." - Unknown
"The brick walls are there for a reason...to stop the people who don't want it badly enough." - Randy Pausch
|
|
|
|
|
Yes, I've tried, but arguments are still wrong in ParseCommandLine. I think it might be a linker problem. The MFC dll is linked to a different CRT than the exe. Is that possible and can I do something about it?
There is sufficient light for those who desire to see, and there is sufficient darkness for those of a contrary disposition.
Blaise Pascal
|
|
|
|
|
sashoalm wrote: The MFC dll is linked to a different CRT than the exe.
I hope you know what you're doing there.
For more info on what you can/can't do with MFC DLLs:
Kinds of DLLs[^]
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
No problem there. We're using vc6 with mfc 4.2. You'd have to be running Windows 3.1 not to have the dlls (ok Windows 95)
There is sufficient light for those who desire to see, and there is sufficient darkness for those of a contrary disposition.
Blaise Pascal
|
|
|
|
|
I have no idea what you're talking about.
I'm talking about mixing CRT libraries between DLLs and EXEs.
I'm not sure what a DLL has to do with this anyway, unless your InitInstance
is in the DLL, in which case the commandline stuff will probably fail
if the DLL is using a different CRT.
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Mark Salsbery wrote: I have no idea what you're talking about.
I thought you were talking about having to redistribute the MFC DLLs.
Sorry about the misunderstanding. I've written in my earlier post 'The MFC dll is linked to a different CRT than the exe'. I meant 'The MFC dll might be linked' and the error might come because of this. Otherwise why would it be correct in my InitInstance, then stop being correct when I step into ParseCommandLine?
I was thinking that there are two copies of __argc and __argv, one for the EXE and one for the MFC DLLs, and ParseCommandLine looks at a different variable. I've had a similar problem when I used a static variable in a function that was inside the class body. I had the variable correctly initialized in one cpp file, then when the function was called from another cpp file, the variable was uninitialized. I found out that I didn't have a single static variable, instead I had a different static variable for each cpp file where the function was invoked.
There is sufficient light for those who desire to see, and there is sufficient darkness for those of a contrary disposition.
Blaise Pascal
|
|
|
|
|
sashoalm wrote: I was thinking that there are two copies of __argc and __argv, one for the EXE and one for the MFC DLLs
Yes, if the DLL is linked to a different CRT than the EXE.
That's why I stated I hope you know what you're doing there
If you mix different versions of MFC and/or the CRT in one process,
then you need to make sure you know what's going on - for example, you can't
allocate an object using "new" in A DLL and try to delete the object in
the EXE if they are using different CRTs. Also you need to be sure initialization
of MFC and the CRT are done properly in the DLL.
The link in my first reply describes those scenarios so you can mix MFC/CRT
properly.
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
I copy/pasted the code of ParseCommandLine in my own CWinApp-derived class, and now it works fine. It seems that the __argc visible from my code and the __argc visible from APPCORE.CPP are two different variables, but I'm still not sure if I have different CRTs. My project is not a dll, and using MFC as a shared DLL is the default in AppWizard. The only thing I've tweaked is setting the CRT to multithreaded dll instead of singlethreaded. Do you have any suggestions how to find out if I have different CRTs? That would be very helpful.
As for the different variables, actually the __argc visible from APPCORE.CPP is a mess of macros and function pointers, and the __argc visible from my code is a variable. Here's the code in MFC about __argc/__argv
#if defined(_DLL) && defined(_M_IX86)
#define __argc (*__p___argc()) /* count of cmd line args */
#define __argv (*__p___argv()) /* pointer to table of cmd line args */
_CRTIMP int * __cdecl __p___argc(void);
_CRTIMP char *** __cdecl __p___argv(void);
#else
_CRTIMP extern int __argc;
_CRTIMP extern char ** __argv;
#endif
#define AFNAME(var) __p_ ## var
#define AFRET(var) &var
_CRTIMP int * __cdecl
AFNAME(__argc) (void)
{
return AFRET(__argc);
}
#define AFRET(var) &var
It looks very complicated.
There is sufficient light for those who desire to see, and there is sufficient darkness for those of a contrary disposition.
Blaise Pascal
|
|
|
|
|
sashoalm wrote: My project is not a dll, and using MFC as a shared DLL is the default in AppWizard. The only thing I've tweaked is setting the CRT to multithreaded dll instead of singlethreaded.
Are you mixing a non-debug multithread CRT DLL with the
debug version of MFC? If so, then there would be two CRTs.
You need to make sure you're using the same CRT library as the
MFC library is using.
You can see what DLLs are loaded int the output window when you run
in the debugger.
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
I found a flag in my linker options - /nodefaultlib:"msvcrtd.lib", after removing it CWinApp::ParseCommandLine works.
But the linker now gives me a warning:
LINK : warning LNK4098: defaultlib "MSVCRT" conflicts with use of other libs; use /NODEFAULTLIB:library
Is this warning a problem?
There is sufficient light for those who desire to see, and there is sufficient darkness for those of a contrary disposition.
Blaise Pascal
|
|
|
|
|
I imagine you're linking a library which is trying to link a
different CRT version.
All warnings are problems IMO.
If it were me, I'd definitely track it down and try to fix it.
If you use the app wizard to create a temporary MFC project,
you'll get a good default set of settings. Compare those to yours...
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
I'm not sure what the cause is exactly but I may be able to offer some help finding it. Clearly you're using MFC and ParseCommandLine is going to be relying on the MFC startup code to provide it with the command line data. This in turn will be getting the data from the C Runtime startup code which runs before MFC gets started. This code in turn gets the command line arguments from the Windows Portable Executable Loader which gets them from the actual 'command line' via Windows itself.
Somewhere a link in this chain has broken and no command line parameters have been stored or passed on to the next stage.
I would start by tracking back the C Runtime startup code to a point where the command line is available e.g. __mainCRTStartup and then track it forward to find where the broken link is. I strongly suspect it will be between the C Runtime and MFC, probably because you need to call some MFC startup code that you aren't calling before calling ParseCommandLine.
"The secret of happiness is freedom, and the secret of freedom, courage."
Thucydides (B.C. 460-400)
|
|
|
|
|
Matthew Faithfull wrote: Somewhere a link in this chain has broken and no command line parameters have been stored or passed on to the next stage
But CWinApp::m_lpCmdLine shows the command line I give correctly. Could it be that ParseCommandLine tries to get it's params from a different avenue?
There is sufficient light for those who desire to see, and there is sufficient darkness for those of a contrary disposition.
Blaise Pascal
|
|
|
|