|
you can contact me , i am from china too. haha
msn: zhu_lin4103@126.com
it's my pleasure to make friend with you.
|
|
|
|
|
大哥 msn 有126 结尾的吗?? 我没找到你啊 ~~~
我msn zhanghui5432@live.com
|
|
|
|
|
Hi all,
I have a class, say GeneralBuilding, which could be one of the classes SmallBuilding, MediumBuilding, LargeBuilding, etc...., depending on the parameters passed to the Building constructor. SmallBuilding, MediumBuilding, and LargeBuilding have a common base class Building.
Is it possible that when i execute
GeneralBuilding x(1) // 1 bedroom...
that x is of a form chosen by the constructor depending on the constructor parameters (i.e. for sake of argument if no. bedrooms = 1 then x would be of class type SmallBuilding, if bedrooms = 2 then x would of type MediumBuilding, and if bedrooms >= 3 then x would be of type LargeBuilding) ?
The reason I'm interested in this is that I need the functionality for each type of GeneralBuilding to change depending on the building size, and i am trying to avoid a bunch of "if then" statements within one class. I'd like to spread the responsibilty to make the classes clean, tidy, safer, more maintainable etc.
I'm looking into it now...
Paul
|
|
|
|
|
No, you can't select the type of the class this way. However, by using pointers (or references), you can manipulate all buildings the same way by manipulating pointers to the base class (this is called polymorphism, google for it if you want more information).
What you could is delegate the instanciation of the class to an external class (a factory class), which will take care of creating the correct type depending of the parameter and will return a pointer to the base class. That's how it is done in general.
|
|
|
|
|
I see. That's a big help. It's still quite clean and neat. "Factory" classes - - i'll bear those in mind !
I guess what I'm ideally after requires an OOP programming language which handles this factory class/pointer business itself, which alas C++ currently does not.
Thanks,
Paul
|
|
|
|
|
paolosh wrote: I guess what I'm ideally after requires an OOP programming language which handles this factory class/pointer business itself, which alas C++ currently does not.
C++ IS an OOP language. This kind of stuff can't be done in Java neither: when you create a class, you always need to know exactly which instance of the class to create, this can't be delegated to the constructor of the base class.
Anyway, if your approach would work, the problem is shifted somewhere else: in the constructor of your base class, you would still need to make a choice based on the parameter, so at that point you would still need to know all existing sub-types.
So, delegating that task to a helper class doesn't change the concept.
|
|
|
|
|
It depends what you want to do. From an OOP point of view, yes the class instantiates to it's own type.
However, from a developer point of view, you may need certain mechanisms to achieve certain tasks.
|
|
|
|
|
paolosh wrote: I guess what I'm ideally after requires an OOP programming language which handles this factory class/pointer business itself, which alas C++ currently does not.
That's not a duty of the OOP language, that's a developer task. Anyway, since it is a well-known, common, problem, it has well-known-state-of-the-art solutions, i.e. design patterns. See the classic GOF's book [^] for reference about creational patterns.
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
[My articles]
|
|
|
|
|
Is it best to use a Factory Class, or would it be the same to use a "create()" function within the class itself.. is one better than the other, or is it just cleaner to use FC's?
|
|
|
|
|
There are several options: one way would be to provide a static Create function within the base class, another would be to delegate that to an external factory class which does only instanciate the class.
I tend to prefer the second option because in the first, you include too much "knowledge" in the base class (it shouldn't know which classes inherits from itself).
|
|
|
|
|
Does it make sense, from an OO design point of view to have such a hierarchy of classes ?
I'm no expert, but I wondering what functionalities a small, medium or large buildings would be
different ?
This signature was proudly tested on animals.
|
|
|
|
|
The buildings theme was simply a demonstration - there are cases in which this arises.
|
|
|
|
|
Hi
I need a timer that doesn't rely on windows.
I need something like:
StartTimer()
CallBack MyJob()
StopTimer()
where MyJob() keeps running every few seconds as controlled by the timer but stops if something calls StopTimer().
I tried using CWnd::SetTimer() (and CWnd::KillTimer()):
int j = 1;<br />
<br />
void CMyClass::StartTimer()<br />
{<br />
CWnd::SetTimer(NULL, 0, 1000, (TIMERPROC) MyFunc);<br />
while(j)<br />
{<br />
MSG msg;<br />
GetMessage(&msg, NULL, 0, 0);<br />
DisplatchMessage(&msg);<br />
}<br />
}<br />
<br />
void CALLBACK CMyClass:MyFunc(HWND hwnd, UINT uMsg, UINT idEvent, DWORD dwTime)<br />
{<br />
DoJob();<br />
--j;<br />
}<br />
<br />
void CMyClass:DoJob()<br />
{<br />
int iN = 0;<br />
}<br />
<br />
void CMyClass::StopTimer()<br />
{<br />
CWnd::KillTimer(NULL, 0);<br />
}<br />
but this means DoJob() only runs once, as the CallBack stops the while loop that dispatches the message. If I don't change j, the program gets stuck runngin DoJob forever, obviously, and the client never gets a chance to call StopTimer().
How do I solve this problem?
Thanks in advance.
|
|
|
|
|
Then you have to rely on WaitForSingleObject.
SetEvent will do the trick for you.
Please refer msdn for more info
Величие не Бога может быть недооценена.
|
|
|
|
|
|
Kiriko wrote: If I don't change j, the program gets stuck runngin DoJob forever, obviously, and the client never gets a chance to call StopTimer().
This is because your implementation of
Kiriko wrote: while(j)
{
MSG msg;
GetMessage(&msg, NULL, 0, 0);
DisplatchMessage(&msg);
}
is wrong. That means GetMessage will wait for getting message and the while loop is running for infinite time.
Btw, I feel you're trying to implement something simple as complicated.
I prefer you try for thread. And the thread function would be something like,
ThreadProc(...)
{
while( j )
{
DoJob();
Sleep( 1000 );
}
}
Usage of events will be better for stopping the thread.
- ns ami -
|
|
|
|
|
Please read my article at IPTECH-OFFSHORE blog. It's in french but the source code you can download might be enough expressive :
http://www.iptech-offshore.net/blog/?p=58[^]
Easy Profiler : a compile-time profiler for C++
www.potatosoftware.com
|
|
|
|
|
Create a extra thread which does the job. WaitForSingleObject() will helo by waiting and also exiting the thread.
Press F1 for help or google it.
Greetings from Germany
|
|
|
|
|
I am currently cross-training to VC++ and I could do with some help if somebody has the time please.
I know this is simple but I just can't get it.
I am using vc++ in VS6. As an exercise, I am building an app with 4 forms. The main form has 3 buttons - btn1, btn2 and btn3 (labelled 'Standard Calculator', 'Math Calculator' and 'Share Calculator' respectively). When a user clicks on a button, I want to display the relevant calculator (form). When the user closes a calculator by clicking the 'Close' button, I want to re-display the main form.
I have built the app in VS6 as a Dialog-based Document but I don't know how to display the secondary forms (the calculators). Should I have used an SDI with multiple forms? I have RTFM (plenty of manuals in fact) but I just can't get it. If I had any hair, I would pull it out.
All help, direction or link will be most appreciated.
RaymondBear
|
|
|
|
|
Using SDI will be a option.
Otherwise you have use more than one dialog.
When you click standard calculator, then you can show the Standard Calc Dialog and hide the normal calc dialog, similarly vice versa.
Величие не Бога может быть недооценена.
modified on Thursday, August 20, 2009 5:26 AM
|
|
|
|
|
Thanks for the response ARJ 09.
The following thread from Cedric Moonen is closer to what I am trying to do.
Any input from you is much appreciated.
I just want control to pass between dialogs. From the main frame to a calculator and back again
but I don't know where to put the code.
RaymondBear
|
|
|
|
|
I guess by "forms" you are talking about a dialog, right ? It is a bit confusing because, in general, the term "forms" relate to managed C++ or C# (AFAIK). If you are 100% that you are doing pure C++ (well, with VC6 I guess that will be the case), then you have to create a new dialog and open that dialog.
To do so, create a new dialog resource in your resource files and open the class wizard. When doing so, it will ask you if you want to create a new class to associate with the resource and you have to say yes.
You can then use this new dialog class in your code and open the dialog by calling the DoModal() method.
You might want to look for more information by googling for dialog and MFC.
EDIT: by the way, choosing between an SDI app or a dialog based app really depends on what you want to do. If you want your calculator top open in a new window (new dialog), and you don't have something like data to be saved (the 'document'), the it is better to stick to a dialog based application because it is easier and you won't need all the stuff provided by an SDI app.
|
|
|
|
|
Thanks Cédric. I appreciate your help.
It is the 'and open the dialog by calling the DoModal() method.' part that I am having trouble with.
This is part of the generated code from my main dialog.
CBearsCalcsDlg dlg;
m_pMainWnd = &dlg;
int nResponse = dlg.DoModal();
if (nResponse == IDOK)
{
// TODO: Place code here to handle when the dialog is
// dismissed with OK
}
else if (nResponse == IDCANCEL)
{
// TODO: Place code here to handle when the dialog is
// dismissed with Cancel
}
/////////////////////////////////////////////////////////////////
I'm guessing that in here I need code that reads something like -
if (btn1 = True)
display form2
elseif (btn2 = True)
display form3
elseif (btn3 = True)
display form4
//////////////////////////////////////////////////////////////////
// Since the dialog has been closed, return FALSE so that we exit the
// application, rather than start the application's message pump.
return FALSE;
RaymondBear
|
|
|
|
|
auitsrxc wrote: It is the 'and open the dialog by calling the DoModal() method.' part that I am having trouble with.
If you followed the previous step, you should have a new class created in your project. When you want to open the dialog, simply create an instance of the class and call DoModal:
CMyNewDialog newDialog;<br />
newDialog.DoModal();
Of course, you need to have the class which has been created by the class wizard. Don't forget to include the header file of the class.
|
|
|
|
|
Thanks Cédric.
It is 22:30 here (Sydney) and I have been cutting mainframe code all day.
I will start a new app tomorrow and follow your advice. I know that one day the penny will drop
and this will all fall into place. It is just not today.
Thanks again.
RaymondBear
|
|
|
|